2011-02-07 24 views
6

Mam pytanie dotyczące tego, jaki mechanizm anulowania trwającej operacji asynchronicznej może zostać użyty, zamiast tokenu anulowania w kontekście async/await. Jestem pewien, że jest to dobrze przemyślana decyzja dotycząca projektu, która bierze pod uwagę imperatywną naturę języka, ale w rzeczywistych sytuacjach, kiedy trzeba przekazać obiekt anulowania do wszystkich twoich asynchronicznych metod, jest przynajmniej trochę bolesna. Istnieją inne pomysły projektowe ze społeczności C#, czy proponowany mechanizm anulowania jest po prostu OK? Chyba coś mi brakuje.async/czekaj na mechanizm anulowania

+0

Mechanizm anulowania za pomocą tokena anulowania wydaje się być kierunkiem, do którego zmierzają rzeczy, w tym w C# 5 CTP na Async. http://msdn.microsoft.com/en-us/vstudio/gg316360. To nie jest połączenie C# 5, ale używam go tutaj, aby wskazać "następną" wersję C#. –

+0

Właśnie zauważyłem, że użyłeś słowa "oczekuj" w swoim pytaniu, więc znasz CTP. Wydaje mi się, że zadanie Task Parallel Library (.NET 4) potwierdziło, że udostępnione przez nią urządzenia były drogą do zrobienia, więc Async CTP używa tego samego paradygmatu. –

+0

Powiązane: http://stackoverflow.com/q/4914374/60761 –

Odpowiedz

4

Token anulowania to najlepsza praktyka, zwłaszcza gdy proces asynchroniczny jest kosztowny, nie ma ustalonego warunku końcowego lub wiąże się z zasobami zewnętrznymi.

Możesz jednak, jeśli chcesz, po prostu "zrezygnować". Zamiast wskazywania wątku asynchronicznego, aby przerwać przetwarzanie i czyszczenie, wystarczy "przerwać"; przestań czekać na zakończenie, odłącz słuchaczy i biegnij dalej. Kiedy wątek zostanie w końcu ukończony, sprawdzi to wydarzenie, zda sobie sprawę, że nikt go nie słucha i cicho kończy. Zaletą jest prostota, jednak istnieje wiele sytuacji, w których byłoby to takie złe:

  • Jeśli proces asynchroniczny zachowa przetwarzania zawsze chyba powiedzieć go zatrzymać, będzie nadal działać w tle, wiążąc do CPU i innych zasobów, aż do zamknięcia aplikacji, w którym to momencie wątek zostanie zabity.
  • Jeśli wątek asynchroniczny wykonuje przerywającą się, odwracalną jednostkę pracy, taką jak operacja DB, jeśli użytkownik naciśnie przycisk Anuluj, spodziewa się, że jak dotąd wszystko, co zostało zrobione, zostało wycofane. Jeśli przestaniesz słuchać i pójdziesz dalej, otrzymają to, co zostało im odebrane.
  • W większości przypadków operacje asynchroniczne wiążą się z zasobami zewnętrznymi, które wymagają czasu, a także wymagają odpowiedniego czyszczenia. Gniazda sieciowe muszą być odłączone, połączenia DB zamknięte, pliki odblokowane itd. Chociaż rezygnacja oznacza, że ​​nie musisz sobie z tym radzić, zamiast tego pozwalając, aby wątek zakończył się normalnie, powszechnym doświadczeniem użytkownika jest to, aby użytkownik miał dość, uderzenia anuluj, a następnie ponów operację. Oznacza to, że zasób użyty w poprzedniej operacji asynchronicznej musi zostać zwolniony, aby użyć go ponownie.
1

Aby anulować operację asynchroniczną, należy wykonać dyskretne czynności, ponieważ operacja ta ma na celu sprawdzenie tokenu anulowania i zatrzymanie się przed kontynuowaniem. To znaczy. Token anulowania to jedynie wzorzec, który ma zostać wdrożony, a nie mechanizm asynchroniczny/oczekiwany.

Co oznacza, że ​​jeśli operacja asynchronizacji jest tylko jednym połączeniem we/wy z uchwytem zakończenia, możesz równie dobrze, po prostu zrezygnować, a nie anulować, ponieważ operacja nie będzie miała uprawnień do sprawdzania tokena do to wezwanie wraca, w którym momencie nie ma nic do zyskania.

A zatem rozważając token anulowania, najpierw należy rozważyć, czy operacja ta może być bardziej wydajna poprzez wspieranie anulowania lub czy po prostu czekanie na zakończenie operacji (np. Użycie mechanizmu limitu czasu) ma więcej sensu.