0

我有一个async我希望能够取消当前调用的方法

        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;

我计划在方法内部检查是否在继续之前请求取消。我在文档中找不到任何示例

我所拥有的不会获得该WebClientRetryAsync方法的令牌,所以这不起作用。

4

1 回答 1

2

如果底层异步方法根本不支持以任何方式取消,那么您根本没有任何方法可以取消它,就是这样,如如何取消不可取消的异步操作?. 您可以在取消令牌被取消后让您的代码继续执行,但是如果底层异步操作无法被告知它应该停止,那么您将无法停止它。

如果您只是想在任务完成时继续前进,假设达到超时,那么您可以使用这些扩展方法来添加该功能:

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是这样调用的结果并且任务被取消,它将引发异常,这就是您支持该路径的方式。

于 2013-12-12T20:47:12.387 回答