簡體   English   中英

如何使用ContinueWith處理任務取消?

[英]How to handle task cancellation using ContinueWith?

我有以下示例:

public void Run()
{
    var ctc = new CancellationTokenSource();

    try
    {
        DoAsync(ctc).Wait();

        Console.WriteLine("Done");
    }
    catch (AggregateException exception)
    {
        Console.WriteLine("Inside try-catch block");
        Console.WriteLine();
        Console.WriteLine(exception);

        exception.Handle(ex =>
        {
            Console.WriteLine(ex.Message);
            return true;
        });
    }
}

private async Task DoAsync(CancellationTokenSource ctc)
{
    Console.WriteLine("DoAsync started");

    await Task.Run(() =>
                Console.WriteLine("DoAsync Run"),
                ctc.Token
            )
            .ContinueWith(antecedent =>
                Console.WriteLine("DoAsync Run cancelled"),
                TaskContinuationOptions.OnlyOnCanceled
            );

    Console.WriteLine("DoAsync finished");
}

我創建了一個方法( DoAsync ),它可以執行一些異步工作,並且可以隨時取消。

如您所見,Task.Run獲取取消令牌。 出於這個原因,我使用continuationOptions = TaskContinuationOptions.OnlyOnCanceled創建了延續任務。

因此,我預計只有在請求取消時才會調用繼續任務,而在其他情況下會被忽略。

但是在我的實現任務中, ContinueWith返回的任務在其前一個任務未被取消時拋出異常:

DoAsync started
DoAsync Run

Inside try-catch block
System.AggregateException...

A task was canceled.

我可以通過添加另一個ContinueWith來解決這個問題,如下例所示:

await Task.Run(() =>
        Console.WriteLine("DoAsync Run"),
        ctc.Token
    )
    .ContinueWith(antecedent =>
        Console.WriteLine("DoAsync Run cancelled"),
        TaskContinuationOptions.OnlyOnCanceled
    )
    .ContinueWith(antecedent => { });

並且此代碼不會拋出任何異常。

但我可以使用單個ContinueWith正確處理取消嗎?

ContinueWith的評論具體說明:

如果未滿足通過continuationOptions參數指定的繼續標准,則將取消繼續任務而不是已安排。

由於您未滿足為先行條件指定的標准(即,未取消),因此將取消延期。 您等待已取消的任務,因此導致DoAsync出現操作取消異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM