實施例:由於垃圾回收,可以調用Task.GetAwaiter()。OnCompleted()失敗嗎?
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
throw new Exception("fault!");
});
task.GetAwaiter().OnCompleted(() =>
{
if (task.IsFaulted)
{
Console.WriteLine(task.Exception);
}
});
上面的代碼等待使用TaskAwaiter任務完成。我在整個網絡的幾個例子中看到了類似這樣的代碼,可以使用OnCompleted或使用GetResult。
爲了使回調正常工作,是否需要明確地保留對awaiter的引用?換句話說,如果在任務結束之前收集器被垃圾收集,這是一個問題嗎?
'我在整個網絡的幾個例子中都看到了類似這樣的代碼,無論是用OnCompleted還是用GetResult.Wow,我當然希望不要;這是一個*可怕的*模式!正如彼得所指出的那樣,如果必須的話,「等待」要遠遠優越 - 甚至是「ContinueWith」。哦,'Task.Run'>'StartNew'和'Task.Exception'會給你一個'AggregateException'而不是你想要的。是的,幾乎所有關於這個代碼片段的東西都不是最理想的。 –
感謝您的反饋!我最終重構了我的設計,並且隨處使用異步/等待更清晰。我不得不繼續使用StartNew,只是因爲它似乎是指定'TaskCreationOptions.LongRunning'的唯一方法,我確實需要它。 – glopes
正如我在我的博客上解釋的,[你可能不需要'LongRunning'](線程池調整)(http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html)在500毫秒內如果你*不通過它。如果你決定保留'StartNew',**一定要明確指定一個調度器**以及'DenyChildAttach'標誌。 –