Entwickler-Ecke

WPF / Silverlight - Dispatcher.BeginInvoke ->Best practice?


Christoph1972 - Di 16.08.11 16:48
Titel: Dispatcher.BeginInvoke ->Best practice?
Hallo zuzusammen,

irgendwie stelle ich mich mit dem invoken mit WPF blöd an. Hier ist nun meine Lösung:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
delegate void MyAutoReader_FileUploadErrorDelegate(object sender, FileUploadEventArgs e);

void MyAutoReader_FileUploadError(object sender, FileUploadEventArgs e)
{
    if (Dispatcher.Thread == Thread.CurrentThread)
    {
        buttonLoadFiles.IsEnabled = true;
        myProgressbar.IsIndeterminate = false;
        MessageBox.Show(e.ErrorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    else
    {
        Dispatcher.BeginInvoke(new MyAutoReader_FileUploadErrorDelegate(MyAutoReader_FileUploadError), new object[] { sender, e })
    }
}


Ist das gut so, kann ich das so lassen?


DareDevil - Mo 29.08.11 11:08

Hi Christoph1972,

schau dir mal "Dispather.CheckAccess" damit kannst du etwas einfacher überprüfen ob du im richtigen Thread bist. Und BeginInvoke braucht kein Object-Array sondern eine ParamList, in deinem Fall würde es dann so aussehen.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
delegate void MyAutoReader_FileUploadErrorDelegate(object sender, FileUploadEventArgs e);

void MyAutoReader_FileUploadError(object sender, FileUploadEventArgs e)
{
    if (Dispatcher.CheckAccess)
    {
        buttonLoadFiles.IsEnabled = true;
        myProgressbar.IsIndeterminate = false;
        MessageBox.Show(e.ErrorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    else
    {
        Dispatcher.BeginInvoke(new MyAutoReader_FileUploadErrorDelegate(MyAutoReader_FileUploadError), sender, e)
    }
}


Gruß Devil


Kha - Mo 29.08.11 12:07

Dieses Pattern mit InvokeRequired/CheckAccess läuft einem oft über den Weg, aber ich konnte damit noch nie etwas anfangen - wie will man bei einem größeren Programm Thread Safety erreichen, wenn man nicht einmal weiß, welche Methode aus welchem Thread aufgerufen wird :nixweiss: . Also einfach festlegen, dass die Methode auf dem Hauptthread ausgeführt werden muss und aus dem Nebenthread heraus invoken. In modernem C# würde zur Parameterübergabe noch Lambdas benutzen, sodass der eigene Delegate-Typ wegfallen kann, und bei einer so kurzen Methode sie selbst wahrscheinlich auch.

C#-Quelltext
1:
2:
3:
4:
5:
Dispatcher.BeginInvoke(new Action(() => {
        buttonLoadFiles.IsEnabled = true;
        myProgressbar.IsIndeterminate = false;
        MessageBox.Show(e.ErrorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}));


Christoph1972 - Di 30.08.11 23:38

Danke Jungs! Eure Vorschläge finde ich schon mal besser.