正如@Evk提到的那樣,您的Continuation
被取消。但我想補充一點,繼續可以被認爲是配置的一部分,並且因此在產生Task
時被設置。考慮以下幾點:
var task = Task.Delay(500).ContinueWith(s =>
{
LogError(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
if (await Task.WhenAny(task, Task.Delay(100)) == task) {
success = true;
} else {
details += "Timed out on SendGrid.";
}
在這種方法您的例外仍然登錄,你的邏輯將繼續只知道該Task
超時。如果除了超時之外,其餘的邏輯確實需要了解Exception
,那麼您將需要再次參考已經討論的await
Task
。
更新爲清楚起見
原始代碼(1)在這個階段,我們不能看到task
定義。
//task is undeclared in this snippet
if (await Task.WhenAny(task, Task.Delay(100)) == task) {
success = true;
}
else {
details += "Timed out on SendGrid.";
await task.ContinueWith(s =>
{
LogError(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
(2)讓我們增加一個模擬的任務只是舉例
var task = Task.Delay(500); //defines task as a Task that will complete in 500ms
if (await Task.WhenAny(task, Task.Delay(100)) == task) {
success = true;
}
else {
details += "Timed out on SendGrid.";
await task.ContinueWith(s =>
{
LogError(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
(3)接下來,當我們await task.ContinueWith
我們允許TaskCancelledException
被拋出。如果刪除await
,則可以忽略Exception
,但我們會收到未等待任務的警告。我們可以忽略該警告,或者我們可以認識到continuation
可以被視爲特定Task
的配置的一部分。隨着我們可以配置我們用適當的選項創建任務的Continuation
,即TaskContinuationOptions.OnlyOnFaulted
:
//Add continuation configuration where task is created
var task = Task.Delay(500).ContinueWith(s =>
{
LogError(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
if (await Task.WhenAny(task, Task.Delay(100)) == task) {
success = true;
} else {
details += "Timed out on SendGrid.";
//removed continuation from here.
}
我並不完全清楚。鑑於我試圖處理漏泄的API,你會如何建議處理這個而不拋出任何異常(和只是日誌記錄)? – SB2055
已更新答案 - 只是在task.ContinueWith之前刪除「await」。 – Evk
然後VS抱怨我沒在等待異步調用。 – SB2055