Komponentem, który umożliwia proste przeniesienie długotrwałych operacji na inny wątek, znany także z Windows Forms jest BackgroundWorker.
W momencie, gdy na obiekcie klasy BackgroundWorker wywołamy metodę RunWorkerAsync zostaje wywołane zdarzenie DoWork. Kod podpięty pod to zdarzenie zostanie wykonany na osobnym wątku. Niektóre z właściwości obiektu BackgroundWorker:
- CancellationPending - flaga czy anulowano zadanie
- IsBusy - flaga czy BW wykonuje zadanie
- WorkerReportsProgress - flaga czy BW może powiadamiać o postępie pracy
- WorkerSupportsCancellation - flaga czy operacja wykonywana przez BW może zostać anulowana
- CancelAsync - przerywa aktualnie wykonywaną operację
- ReportProgress - wywołuje zdarzenie ProgressChanged
- RunWorkerAsync - uruchamia operacje
- DoWork - zdarzenie, które jest wywoływane w momencie wywołania metody RunWorkerAsync
- ProgressChanged - zdarzenie wywoływane w momencie wywołania metody ReportProgress
- RunWorkerCompleted - zdarzenie wywoływane w momencie zakończenia operacji przez BW
- przesłanie danych do naszego nowego wątku - parametr przekazujemy w wywołaniu metody RunWorkerAsync, a odebranie parametru następuje przez właściwość DoWorkEventArgs.Argument
- powiadomienie, że proces zakończył się - realizowane poprzez obsłużenie zdarzenia RunWorkerCompleted
- zwrócenie obliczanej wartości - przypisujemy wartość do właściwości - DoWorkEventArgs.Result, a odbieramy ją w zdarzeniu RunWorkerCompleted.Result
- anulowanie operacji - ustawiamy flagę WorkerSupportsCancellation; w zdarzeniu DoWork implementujemy logikę, która sprawdza co jakiś czas flagę CancellationPending i jeżeli flaga jest ustawiona, przerywa operację
- raportowanie postępów - ustawiamy flagę WorkerReportsProgress; w kodzie, metody która wykonuje długotrwałe obliczenia wywołujemy metodę ReportProgress do której przekazujemy informację o procencie wykonanej pracy
Code:
Aplikacja do pobrania z linka: http://sdrv.ms/V0bXkg
Delegaty
Delegaty umożliwiają implementację asynchronicznych metod. Każda delegata posiada metody: BeginInvoke oraz EndInvoke. Wywołanie pierwszej z nich powoduje stworzenie osobnego wątku i wykonania w nim wskazywanej metody. Druga metoda pozwala na pobranie rezultatu wykonania metody.
Delegaty możemy użyć na trzy sposoby w celu tworzenia metod asynchronicznych:
- wywołujemy BeginInvoke, wykonujemy zadanie a następnie wywołujemy EndInvoke na tym samym wątku
- wywołujemy BeginInvoke a następnie oczekując na zakończenie wywołania, wykonujemy inne operacje
- wywołanie metody po zakończeniu pracy wątku w tle
Code:
Drugi przypadek zakład iż, w czasie oczekiwania na rezultat wykonania się operacji w innym wątku, będziemy wykonywać inne rzeczy w głównym wątku:
Code:
Ostatnia możliwość zakłada, iż rezultat wykonania operacji asynchronicznej nie będzie nam potrzebny w wątku, który go wykonał. Po zakończeniu obliczeń, zostanie wywołana metoda, w której możemy odebrać naszą wartość:
Code:
Kod do pobrania: http://sdrv.ms/RPK8iZ
Wątki
Chcąc mieć 100% kontrolę nad wątkami, możemy skorzystać z klasy Thread. Podstawowe operacje w przypadku pracy z wątkami:
1. Tworzenie wątku:
Code:
2. Niszczenie wątku:
Wątek można zniszczyć za pomocą metody Abort. Wywołanie tej metody na działającym wątku spowoduje rzucenie wyjątku ThreadAbortException:
Code:
3. Synchronizacja wątków
Zakleszczenia (deadlock) - występują gdy procesy czekają nawzajem na siebie - żaden nie jest w stanie ukończyć pracy
Sytuacje wyścigu (race conditions) - występują w momencie gdy więcej niż jeden proces odwołuje się do niezabezpieczonej pamięci współdzielonej
Do synchronizacji możemy wykorzystać słowo kluczowe lock:
Code:
Wątki a kontrolki
Kontrolki na formatce obsługuje wątek nazywany UI Thread. Dostęp do kontrolek z innych wątków nie jest bezpieczny. Windows Forms jak i WPF definiują wzorce dostępu do wątku interfejsu:
Windows Forms:
Za pomocą delegaty odwołujemy się do wątku interfejsu:
Code:
WPF:
Za pomocą obiektu Dispatcher, wykonujemy zmiany w interfejsie:
Code:
Pierwsza metoda jest blokująca. Druga nie zablokuje wątku interfejsu w czasie jego aktualizacji.
Brak komentarzy:
Prześlij komentarz