簡體   English   中英

將 OperationCanceledException 與 CancellationToken 相關聯的正確方法

[英]Proper way to correlate an OperationCanceledException to a CancellationToken

我正在使用支持取消的異步 api,並且我正在向該 api 傳遞一個CancellationToken實例。 像往常一樣,如果在傳遞的令牌上請求取消,我正在調用的 api 將拋出OperationCanceledException (這是 .NET 框架的標准協作取消模式)。

當且僅當它是由於取消提供的取消令牌而引發的異常時,我希望能夠捕獲OperationCanceledException

以下代碼說明了我要實現的目標:

try 
{
    await _service.DoSomethingAsync(cancellationToken: token);
}
catch (OperationCanceledException ex) when ( /* here I want a condition signifying that the OperationCanceledException is caused by the cancellation of the token object */)
{
    // avoid logging the exception: this is raised by design (cooperative cancellation)
    throw;
}
catch (Exception ex) 
{
    _logger.LogError(ex, "An error occurred: {0}", ex.Message);
    throw;
}

對於上面代碼的異常過濾器我基本上有兩個想法:

  • 檢查token object 上的IsCancellationRequested屬性: when (token.IsCancellationRequested)
  • 檢查ex object 上的CancellationToken屬性: when (ex.CancellationToken == token)

進行我要執行的檢查的正確方法是什么? 上面顯示的兩種方式是否等效? 有最佳實踐嗎?

重要提示:我知道上面顯示的代碼可以以更有效的方式編寫,因為捕獲異常是一項昂貴的操作。 最好的辦法可能是完全刪除第一個catch塊,並且僅當且僅當它與token object 的取消無關時才捕獲Exception 我知道這一點,但這不是我問題的重點。 我以這種方式編寫問題中的代碼只是為了清楚起見,因為我的問題的重點是如何正確地將OperationCanceledException與導致異常本身的CancellationToken相關聯。

當且僅當它是由於取消提供的取消令牌而引發的異常時,我希望能夠捕獲 OperationCanceledException。

您不能完全做到這一點,但您可以“僅當我提供的令牌已被取消時才捕獲已取消的異常”,這通常已經足夠了。

when (token.IsCancellationRequested)是你想要的。

不要檢查ex.CancellationToken ,因為您調用的方法可能正在觀察鏈接的取消令牌,這與您提供的不同。

暫無
暫無

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

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