我會得到AggregateException
異常,因爲我還沒有檢查 的Exception
財產?
不,你會得到一個例外,因爲任務g
由TPL取消(因爲,正如MSDN指出,這個任務就不會,如果antescendent任務拋出一個異常預定)。
我們有3個任務在這裏:
- 原始任務(即使用StartNew)
- 第一凸起的任務(即拋出異常)
- 第二後續任務(即打印OK)(此爲g來自您的代碼的任務)。
問題是,如果第二項任務將成功完成,您要求TPL啓動3d任務。這意味着如果這個條件不符合TPL將完全取消你新創建的任務。
你有沒有觀察到任務異常,因爲你有臨時任務(任務2在我的列表),你從來沒有觀察到。因爲你從來沒有觀察到它的故障狀態,它會拋出終結器來告訴你。
您可以通過打印在catch塊任務的狀態檢查:
catch (AggregateException ex)
{
Console.WriteLine("catch");
// Will print: Status in catch: Canceled
Console.WriteLine("Status in catch: {0}", g.Status);
}
必須的,如果前因拋出一個例外,我總是檢查(每 行?)? (我不能檢查各行它沒有任何意義和 很煩人!)
是的,你應該遵守先行任務例外,以避免此問題:
static class TaskEx
{
public static Task ObserverExceptions(this Task task)
{
task.ContinueWith(t => { var ignore = t.Exception; },
TaskContinuationOptions.OnlyOnFaulted);
return task;
}
}
,然後用它如下:
var g= Task.Factory.StartNew<int> (() => 8)
.ContinueWith (ant =>{throw null;})
.ObserveExceptions()
.ContinueWith (a =>{ Console.WriteLine("OK");});
try{
Console.WriteLine("1");
g.Wait();
Console.WriteLine("2");
}
catch (AggregateException ex)
{Console.WriteLine("catch"); }
UPDATE:加溶液最後一顆子彈
是不是try catch塊應該吞下異常? (我 認爲所有的異常泡到wait方法....這樣嗎?)
我們已成立的擴展方法在我們的項目(稱爲TransformWith
)的,可以解決這一具體問題和增益如下:
- 異常將向上冒泡到catch塊和
- 我們將不會與
TaskUnobservedException
這裏的美國崩潰的應用程序GE
var g = Task.Factory.StartNew(() => 8)
.ContinueWith(ant => { throw null; })
// Using our extension method instead of simple ContinueWith
.TransformWith(t => Console.WriteLine("OK"));
try
{
Console.WriteLine("1");
// Will fail with NullReferenceException (inside AggregateExcpetion)
g.Wait();
Console.WriteLine("2");
}
catch (AggregateException ex)
{
// ex.InnerException is a NullReferenceException
Console.WriteLine(ex.InnerException);
}
這裏是一個擴展方法:
static class TaskEx
{
public static Task TransformWith(this Task future, Action<Task> continuation)
{
var tcs = new TaskCompletionSource<object>();
future
.ContinueWith(t =>
{
if (t.IsCanceled)
{
tcs.SetCanceled();
}
else if (t.IsFaulted)
{
tcs.SetException(t.Exception.InnerExceptions);
}
else
{
try
{
continuation(future);
tcs.SetResult(null);
}
catch (Exception e)
{
tcs.SetException(e);
}
}
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
}
_is,如此罕見的話題_ –
唉,這個話題是不是如此罕見。我在自定義的'TaskEx'類中使用了幾種擴展方法來處理它。 –
什麼是唉? –