【问题标题】:Sending a Cancellation Token in a Task<TResult>在 Task<TResult> 中发送取消标记
【发布时间】:2013-12-12 20:13:46
【问题描述】:

我有一个 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;

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

我没有得到WebClientRetryAsync方法的令牌,所以这行不通。

【问题讨论】:

    标签: c# task cancellation cancellation-token


    【解决方案1】:

    如果底层异步方法根本不支持以任何方式取消,那么您根本无法取消它,就是这样,正如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 这样的调用结果并且任务被取消,它将抛出异常,这就是您支持该路径的方式。

    【讨论】:

      猜你喜欢
      • 2022-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2020-11-23
      • 1970-01-01
      相关资源
      最近更新 更多