Falscher Thread? Kein Problem!

Hmpf.. mal wieder eine Exception wegen einer Aktion aus einem falschen Thread? Wiedermal notwendige Asynchronität die dennoch der Entwicklung im Weg steht. Naja viele kennen dieses Problem bereits und jeder hat seine Lösungen hierfür. Allerdings ist dies oft so das es sich bei diesen „Lösungen“ um Copy&Paste handelt, welches nicht zwingend zur Wartbarkeit von Sourcecode beiträgt. Wie wäre es jetzt also, wenn wir eine Klasse hätten welche unsere Aktionen mit dem richtigen Thread Synchronisiert? Das wäre doch fantastisch, oder etwa nicht? Exakt eine solche Klasse befindet sich in vielen MVVM-Frameworks und auch außerhalb solcher Frameworks ist diese immer mal wieder eine große Hilfe. Den asynchrone Operationen lassen sich nicht vermeiden, spätestens wenn längere Prozesse direkt vom GUI-Thread gestartet werden und dies die Benutzeroberfläche einfriert ist Asynchronität gefragt. Allerdings möchte man hier auch wenn die Daten sich verändern, dass die Benutzeroberfläche dies soweit mit bekommt. Hierfür haben wir zwar bereits eine PropertyChangedBase-Klasse gebaut, aber diese ist nun mal nicht in der Lage Aktionen aus anderen Threads durchzuführen. 

Um nun also unsere Erweiterung wirken zu lassen, benötigen wir weitere Methoden. Ich habe hierfür die Klasse „ViewModel“ erstellt, welche auf den Bereits existierenden Klassen PropertyChangedBase sowie ExtendedPropertyBase aufbaut. Aber werfen wir zunächst einmal einen Blick auf den Sourcecode.

public abstract class ViewModel : ExtendedPropertyBase
{
    #region Default context

    public void SendToUiThread(Action action)
    {
        uiContext.Send(state => action.Invoke(), null);
    }

    public void PostToUiThread(Action action)
    {
        uiContext.Post(state => action.Invoke(), null);
    }

    #endregion

    #region Custom context

    public void SendToThread(Action action, SynchronizationContext context)
    {
        context.Send(state => action.Invoke(), null);
    }

    public void PostToThread(Action action, SynchronizationContext context)
    {
        context.Post(state => action.Invoke(), null);
    }

    #endregion
}

Wie hier direkt zu sehen ist, benutzen wir den „uiContext“ aus der PropertyChangedBase. Aufgerufen kann das ganze anschließend einfach mittels „SendToUiThread(() => MeineMethode());“ also mittels Lambda-Expression. Abschließend sorgt dies nun dafür, dass wir die „InvalidOperationException“ aufgrund eines falschen Threads in Zukunft nur noch in Foren sehen, von Leuten die dies noch nicht nutzen. Ich hoffe dass auch diese Klasse seinen nutzen findet und einigen Helfen konnte. Feedback ist natürlich wieder gern gesehen und die Klasse könnt ihr hier herunterladen.