2013-12-12 3 views
0

У меня есть async метод, который я хочу, чтобы иметь возможность отменить, что в настоящее время называетсяОтправка отмены токен в задаче <TResult>

 string html = await Html.WebClientRetryAsync(state); 

Я пытался выяснить синтаксис, чтобы быть в состоянии назвать это метод, передающий ему CancellationToken. Вот что я сделал до сих пор.

 CancellationToken ct; 
     Func<object, Task<string>> func = async (s) => await WebClientRetryAsync((string)s); 
     Task<Task<string>> task = Task<Task<string>>.Factory.StartNew(func, state.Uri.AbsoluteUri, ct); 
     string html = await task.Result; 

Я планирую проверить внутри метода, чтобы узнать, была ли запрошена отмена до начала работы. Я не мог найти ни одного примера в documentation

То, что я не получите маркер метода WebClientRetryAsync, так что это не будет работать.

ответ

2

Если базовый метод асинхронизации просто не поддерживает отмену в любом случае, то просто нет способа отменить его, и это все, как описано в How do I cancel non-cancelable async operations?. Вы можете продолжить выполнение кода после того, как маркер отмены будет отменен, но если базовая асинхронная операция не будет передана, она должна прекратиться, вы не сможете ее остановить.

Если вы просто хотите способ перемещения, когда заканчивается задание, принимая тайм-аут будет достигнуто, то вы можете использовать эти методы расширения для добавления этой функции:

public static Task AddCancellation(this Task task, CancellationToken token) 
{ 
    return Task.WhenAny(task, task.ContinueWith(t => { }, token)) 
     .Unwrap(); 
} 
public static Task<T> AddCancellation<T>(this Task<T> task, 
    CancellationToken token) 
{ 
    return Task.WhenAny(task, task.ContinueWith(t => t.Result, token)) 
     .Unwrap(); 
} 

понимаю конечно, что если вы await результат вызова, подобного этому, и задача отменяется, он выдает исключение, так как вы поддерживаете этот путь.