Answers:
如果创建一个Task,并且您从未调用task.Wait()
或尝试检索a的结果Task<T>
,则当垃圾收集器收集该任务时,它将在完成过程中关闭您的应用程序。有关详细信息,请参见TPL中 MSDN上有关异常处理的页面。
最好的选择是“处理”异常。这可以通过延续来完成-您可以将延续附加到任务,并记录/吞咽/等发生的异常。这提供了一种记录任务异常的干净方法,并且可以编写为简单的扩展方法,即:
public static void LogExceptions(this Task task)
{
task.ContinueWith( t =>
{
var aggException = t.Exception.Flatten();
foreach(var exception in aggException.InnerExceptions)
LogException(exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
通过上述操作,您可以通过以下方式阻止任何任务拆解应用程序并对其进行记录:
Task.Factory.StartNew( () =>
{
// Do your work...
}).LogExceptions();
或者,您可以订阅TaskScheduler.UnobservedTaskException并在那里进行处理。
当然; 这意味着将Task
其留给垃圾收集后完成,但是任务本身失败了。有两个修复程序:
ContinueWith(...)
订阅,检查.IsFaulted
和.Exception
对Task
在参数)TaskScheduler.UnobservedTaskException
事件并标记为已观察到(e.SetObserved()
记录错误后调用)IsFaulted
,则可以使用OnlyOnFaulted
继续选项,而无需手动检查...
SetObserved
on UnobservedTaskExceptionEventArgs
。
试试这个:
public static void ThrowFirstExceptionIfHappens(this Task task)
{
task.ContinueWith(t =>
{
var aggException = t.Exception.Flatten();
foreach (var exception in aggException.InnerExceptions)
{
throw exception; // throw only first, search for solution
}
},
TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations
}
public static Task CreateHandledTask(Action action)
{
Task tsk = Task.Factory.StartNew(action);
tsk.ThrowFirstExceptionIfHappens();
return tsk;
}
Off
在您选择的名为四个字母的单词的类中使用静态存根方法,并将其用于包罗万象的延续。有助于消除由于这种特殊异常而导致的一些沮丧情绪。