Entwickler-Ecke

WinForms - Threadübergreifende Vorgänge: Events mit Parametern


darkdust - Fr 16.07.10 15:44
Titel: Threadübergreifende Vorgänge: Events mit Parametern
Hallo Leute,
ich schreibe im Moment an einer Kalendersynchronisation mit der Google-API. Meine Prozedur Sync() benötigt etwa 10-20 sek. für eine Synchronisation. In dieser Zeit friert natürlich mein Formular ein.
Das wollte ich beheben indem ich die Prozedur in einen eigenen Thread gelegt habe:


C#-Quelltext
1:
2:
Thread SyncThread = new Thread(new ThreadStart(StarteSynchronisation));
SyncThread.Start();



C#-Quelltext
1:
2:
3:
4:
5:
6:
        public void StarteSynchronisation()
        { 
            TerminColl = new TerminCollection();
            TerminTemplate.OnTerminMessage = new TerminTemplate.HandlerTerminMessage(OnMessage);
            TerminColl.SyncCollectionWithDatabase();
        }



C#-Quelltext
1:
2:
3:
4:
        public void OnMessage(EventArgsTerminProtocolMessage e)
        {
            richTextBox1.Text += "Priority: " + e.EnPriority.ToString() + " " + e.DTTime + ": " + e.SMessage;
        }


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
    public class EventArgsTerminProtocolMessage : EventArgs
    {
        public EventArgsTerminProtocolMessage(DateTime DTTime, String SMessage, EnumMessagePriority EnPriority)
        {
            this.DTTime = DTTime;
            this.SMessage = SMessage;
            this.EnPriority = EnPriority;
        }

        public readonly DateTime DTTime;
        public readonly String SMessage;
        public readonly EnumMessagePriority EnPriority;
    }


Allerdings werden die Statusmeldungen per Event zurückgegeben was zu dem Fehler "Ungültiger threadübergreifender Vorgang...) führt.

Ich hatte gelesen das ein einfaches "Invoke" mein Problem lösen könnte (Synchronisation der Threads):

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
        public void OnMessage(EventArgsTerminProtocolMessage e)
        {
            if (InvokeRequired)
                Invoke(new EventHandler(OnMessage(e)));
            else
                richTextBox1.Text += "Priority: " + e.EnPriority.ToString() + " " + e.DTTime + ": " + e.SMessage;
        }


Hier erhalte ich allerdings nur die Meldung "Method name expected". Was kann ich noch versuchen?


Yogu - Fr 16.07.10 15:55

Hallo,

user profile icondarkdust hat folgendes geschrieben Zum zitierten Posting springen:
Ich hatte gelesen das ein einfaches "Invoke" mein Problem lösen könnte

Das ist korrekt.

user profile icondarkdust hat folgendes geschrieben Zum zitierten Posting springen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
        public void OnMessage(EventArgsTerminProtocolMessage e)
        {
            if (InvokeRequired)
                Invoke(new EventHandler(OnMessage(e)));
            else
                richTextBox1.Text += "Priority: " + e.EnPriority.ToString() + " " + e.DTTime + ": " + e.SMessage;
        }

Das ist nicht korrekt. ;)

OnMessage(e) ruft die Methode auf und gibt den Rückgabewert zurück (void). new EventHandler(...) erwartet aber die Methode selbst, nicht einen Aufruf dieser. Was du machen musst, ist folgendes:


C#-Quelltext
 
4:
/* ... */
Invoke(new TerminTemplate.HandlerTerminMessage(OnMessage), e);

Erstens kannst du hier nicht EventHandler verwenden, da die Methode OnMessage andere Parameter hat als EventHandler. Zweitens müssen die Parameter, die an die Methode übergeben werden sollen, als Parameter von Invoke, nicht von OnMessage, angegeben werden.

Grüße,
Yogu


darkdust - Fr 16.07.10 16:01

Danke, jetzt funktioniert es ^^


Delete - Fr 16.07.10 17:06

Ja ist echt ne supi Lösung. :dance2: :rofl: :dance2: