Отправка токена отмены в Task‹TResult›

У меня есть метод 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, поэтому это не сработает.


person Harrison    schedule 12.12.2013    source источник


Ответы (1)


Если базовый асинхронный метод просто не поддерживает отмену каким-либо образом, у вас просто нет способа отменить его, и это все, как обсуждается в Как отменить неотменяемые асинхронные операции?. Вы можете продолжить выполнение своего кода после отмены маркера отмены, но если базовая асинхронная операция не имеет возможности сказать, что она должна быть остановлена, у вас нет возможности ее остановить.

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

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 получите результат такого вызова и задача будет отменена, она вызовет исключение, и именно так вы бы поддержали этот путь.

person Servy    schedule 12.12.2013