Dipatching & UIThread

Das App-Template verwendet den aktuellen Dispatcher von der Applikation Application.Current.Dispatcher, um zum Beispiel den aktuellen Dispatcher in das ViewModel zu injizieren. Somit steht immer der richtige Dispatcher zur Verfügung und Code, welcher auf dem UIThread ausgeführt werden muss, kann einfach über unseren DispatchManager ausgeführt werden. Das passiert im BaseViewModel und alle weiteren ViewModels, welche von…

Image Description

Das App-Template verwendet den aktuellen Dispatcher von der Applikation Application.Current.Dispatcher, um zum Beispiel den aktuellen Dispatcher in das ViewModel zu injizieren. Somit steht immer der richtige Dispatcher zur Verfügung und Code, welcher auf dem UIThread ausgeführt werden muss, kann einfach über unseren DispatchManager ausgeführt werden. Das passiert im BaseViewModel und alle weiteren ViewModels, welche von dieser Klasse erben, muss der Dispatcher wie unten zugewiesen werden.

Constructor (ctor)

Damit eine View bzw. ein ViewModel auch den Dispatcher empfangen kann, muss der Ctor wie folgt angepasst werden (sofern Ihr eine neue View bzw. ein neues ViewModel anlegt).

ViewModel

Das neue ViewModel sollte immer vom BaseViewModel oder AppViewModel erben. Damit erhält es Zugriff auf alle gemeinsam genutzten Funktionen und Methoden. Der Ctor kann als Parameter einen IDispatcher annehmen, und diesen auch an die Basis-Klasse weitergeben. Andernfalls wird einfach der aktuelle Dispatcher der Applikation gesetzt.

public partial class BaseViewModel
{
    #region Ctor
    public BaseViewModel()
    {
        Dispatcher = Application.Current.Dispatcher;
    }
  
    public BaseViewModel(IDispatcher dispatcher)
    {
        Dispatcher = dispatcher;
    }
    #endregion

    // Some code...
}

// Custom ViewModel 
public partial class DashboardPageViewModel : BaseViewModel
{
    #region Ctor
    public DashboardPageViewModel() : base(dispatcher)
    {
        Dispatcher = Application.Current.Dispatcher;
    }
    #endregion

    // Some code...
}

Views

In der View muss der Ctor dann das gewünschte ViewModel als Parameter übergeben werden.

public partial class DashboardPage : ContentPage
{
    public DashboardPage() 
	{         
    	InitializeComponent();
    	var viewModel = new DashboardPageViewModel();
    	BindingContext = viewModel;
	}
}

DispatchManager

Der DispatchManager ist eine Helper-Klasse, welche es Ihnen einfach ermöglicht Code über den Dispatcher auszuführen. Durch das vorgeschaltete trycatch werden auch direkt Fehler abgefangen und protokoliert (EventManger).

Einfaches Beispiel

Hier wird die Eigenschaft „IsRefreshing“ Thread-Safe auf „false“ gesetzt.

DispatchManager.Dispatch(Dispatcher, () => IsRefreshing = false);

Da es sich bei dieser Eigenschaft um ein Element handelt, welches ein Binding auf ein UI-Element hat, muss dieses zwangsweise am MainThread der Applikation ausgeführt werden. Andernfalls kann es hier zu einer Ausnahme bzw. einen Crash kommen.

CodeSnippet dispatchen

Um einen ganzen Codeblock zu dispatchen, kann die Funktion wie folgt aussehen.

DispatchManager.Dispatch(Dispatcher, () =>
{
    CurrentJobInfo = DemoManager.JobInfo;
    PrintersState = DemoManager.PrinterState.Printer;
    ServerSettings = DemoManager.ServerSettings;
    Files = DemoManager.Files;
});

Dispatching abwarten

Manchmal kann es nötig sein, dass Dispatching abzuwarten (await). Dazu muss die DispatchAsync() Methode verwendet werden.

await DispatchManager.DispatchAsync(Dispatcher, UpdateFromInstanceData);
// Or
await DispatchManager.DispatchAsync(Dispatcher, () =>
{
    IsRefreshing = true;
    IsReachable = false;

    SelectedServer = Servers.FirstOrDefault(server => server.Id == LastServerId);
    SelectedServerAddress = SelectedServer?.FullWebAddress;
});
await CheckOnlineStateSelectedServer();

War dieser Artikel hilfreich für Sie?

Ja Nein

Verwandte Artikel