Дополнительно
Как отменить задачу в await?
Я'играю с этими задачами Windows 8 WinRT, и я'пытаюсь отменить задачу, используя метод ниже, и это работает до некоторой степени. Метод CancelNotification DOES вызывается, что заставляет вас думать, что задача была отменена, но в фоновом режиме задача продолжает выполняться, а после ее завершения статус задачи всегда остается завершенным и никогда не отменяется. Есть ли способ полностью остановить задачу, когда она отменяется?
private async void TryTask()
{
CancellationTokenSource source = new CancellationTokenSource();
source.Token.Register(CancelNotification);
source.CancelAfter(TimeSpan.FromSeconds(1));
var task = Task<int>.Factory.StartNew(() => slowFunc(1, 2), source.Token);
await task;
if (task.IsCompleted)
{
MessageDialog md = new MessageDialog(task.Result.ToString());
await md.ShowAsync();
}
else
{
MessageDialog md = new MessageDialog("Uncompleted");
await md.ShowAsync();
}
}
private int slowFunc(int a, int b)
{
string someString = string.Empty;
for (int i = 0; i < 200000; i++)
{
someString += "a";
}
return a + b;
}
private void CancelNotification()
{
}
147
4
Ознакомьтесь с Cancellation (который был введен в .NET 4.0 и практически не изменился с тех пор) и Task-Based Asynchronous Pattern, который содержит рекомендации по использованию
CancellationToken
с методамиasync
.Вкратце, вы передаете
CancellationToken
в каждый метод, который поддерживает отмену, и этот метод должен периодически проверять его.Или для того, чтобы избежать модификации
slowFunc
(например, у вас нет доступа к исходному коду):Вы также можете использовать красивые методы расширения из https://github.com/StephenCleary/AsyncEx, и тогда все будет выглядеть просто:
Один случай, который до сих пор'т был покрыт как обработка отмены внутри асинхронного метода. Возьмем для примера простой случай, когда вам нужно, чтобы загрузить некоторые данные в службу заставить его что-то подсчитать и затем вернуть результаты.
Если вы хотите поддерживать отмену, то проще всего будет передать маркер и проверить, если он был отменен между каждым вызовом асинхронного метода (или через ContinueWith). Если они очень длительные звонки, хотя вы могли бы ждать некоторое время, чтобы отменить. Я создал небольшой вспомогательный метод, а не плохо, как только отменили.
Поэтому использовать его тогда просто добавьте `.WaitOrCancel(маркер) для любого асинхронного вызова:
Обратите внимание, что это не остановит задания, вы ждали и она будет продолжать работать. Вы'll необходимо использовать другой механизм, чтобы остановить его, такие как
CancelAsync позвонить в Примере, а еще лучше сдать в той же
CancellationTokenк
задача`, так что он может обрабатывать отмену в конце концов. Пытаясь прервать поток разве'т рекомендуется.Я просто хочу добавить к уже принятому ответу. Я застрял на этом, но я пошел другим путем в обработке завершенного события. Вместо того чтобы запускать await, я добавляю обработчик завершения к задаче.
Где обработчик события выглядит следующим образом
С этим маршрутом вся обработка уже сделана за вас, когда задача отменяется, она просто запускает обработчик события, и вы можете увидеть, была ли она отменена там.