W tym odcinku będzie o Manage application responsiveness – czyli Dispatcher
DispatcherObject
Większość obiektów w WPF dziedziczy po tej właśnie klasie a przez to niestety nie są thread-safety. Jeśli chcemy zmieniać właściwości tych obiektów z innego wątku niż ten w którym zostały utworzone, musimy posłużyć się specjalnym mechanizmem. Na szczęście klasa ta udostępnia specjalną właściwość Dispatcher, którą możemy wykorzystać do tego celu.
Przykładowy kod, który możemy do tego celu wykorzystać:
void method(object obj)
{
var przycisk = (obj as Button);
if (przycisk == null) return;
if (przycisk.Dispatcher.CheckAccess()) // 1
{
przycisk.Content = “Update z wątku”;
}
else
{
przycisk.Dispatcher.Invoke(DispatcherPriority.Normal,
new Action<Button>(method), obj); //2
}
}
Najważniejsze są tu linie 1 oraz 2. W 1 sprawdzamy, czy jesteśmy w tym samym wątku, w którym została utworzona nasza kontrolka przycisk i jeśli tak to zmieniamy właściwość kontrolki. Jeśli nie używamy obiektu Dispatcher to wywołania naszej metody (2).
DispatcherPriority
W przypadku WPF’a mamy całkiem sporo możliwości konfigurowania priorytetu naszej aplikacji. Enumeracja DispatcherPriority oferuje, aż 12 różnych wartości. Znaleźć je wszystkie możemy na MSDN. Na początku ilość może przytłaczać, ale dzięki takiemu rozróżnieniu możemy precyzyjnie zaplanować nasze wątki.
Zwracanie wartości z wątków
Jeśli nasza metoda zwraca wartość to w głównym wątku możemy chcieć ją odczytać. Aby to zrobić możemy posłużymy się mniej więcej takim kodem:
var result = Dispatcher.BeginInvoke(new Func<object, bool>(method), przycisk);
result.Wait();
MessageBox.Show(result.Result.ToString());
Freezable Objects
Obiekty, które dziedziczą z tej klasy mogą znaleźć się w specjalnym stanie “zamrożenia”, w którym dostępne są tylko do odczytu. Są wtedy również thread-safe. Aby sprawdzić czy czy dany obiekt jest zamrożony wystarczy zawołać właściwość IsFrozen, aby sprawdzić czy obiekt może zostać zamrożony CanBeFrozen.Przykładowe klasy to: Brush, Pen, Geometry, Transform, AnimationTimeline.Po co takie obiekty nam są? Ponoć poprawiają wydajność naszych aplikacji w WPF oraz udostępniają szczegółowe notyfikacje o swoim stanie.
Następnym razem nowy temat – Building user interfaces. Zaczniemy od Content controls.
Founder of Octal Solutions a .NET software house.
Passionate dev, blogger, occasionally speaker, one of the leaders of Wroc.NET user group. Microsoft MVP. Podcaster – Ostrapila.pl