Niektóre System.Threading.Tasks.Task
konstruktory przyjmują CancellationToken
jako parametr:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
Zaskakuje mnie to, że z wnętrza metody nie ma sposobu, aby faktycznie dostać się do przekazanego tokena (np. Nic podobnego Task.CurrentTask.CancellationToken
). Token musi być dostarczony przez inny mechanizm, taki jak obiekt stanu lub przechwycony w lambda.
W jakim celu służy token anulowania w konstruktorze?
Parallel.For
lubParallel.ForEach
Konstruktor używa tokena do wewnętrznego anulowania. Jeśli Twój kod chce uzyskać dostęp do tokena, jesteś odpowiedzialny za przekazanie go tobie. Gorąco polecam przeczytanie książki o programowaniu równoległym z Microsoft .NET w CodePlex .
Przykład użycia CTS z książki:
źródło
token.ThrowIfCancellationRequested();
? W moim teście zachowanie jest takie samo. Jakieś pomysły?when cts.Cancel() is called the Task is going to get canceled and end, no matter what you do
. Jeśli zadanie zostanie anulowane przed jego uruchomieniem, zostanie anulowane . Jeśli treść zadania nigdy nie sprawdza żadnego tokena, uruchomi się on do końca, co spowoduje status RanToCompletion . Jeśli ciało wyrzuciOperationCancelledException
np. PrzezThrowIfCancellationRequested
, wówczas Task sprawdzi, czy token Cancellation tego wyjątku jest taki sam jak ten powiązany z Zadaniem. Jeśli tak, zadanie jest anulowane . Jeśli nie, to nic zarzucić .Anulowanie nie jest prostym przypadkiem, jak wielu może pomyśleć. Niektóre subtelności są wyjaśnione w tym poście na blogu na msdn:
Na przykład:
Anulowanie w rozszerzeniach równoległych
źródło
Oto przykład, który pokazuje dwa punkty w odpowiedzi przez Maxa Galkin :
Wynik:
źródło