与此答案相关,
如果我真的想要"Fire and Forget"一个确实返回任务的方法,并且(为简单起见)让我们假设该方法不会抛出任何异常.我可以使用答案中列出的扩展方法:
public static void Forget(this Task task)
{
}
Run Code Online (Sandbox Code Playgroud)
使用这种方法,如果存在错误,则会Task引发异常,然后抛出意外异常时,异常将被吞下并被忽视.
问题:在这种情况下,扩展方法的形式是否更合适:
public static async void Forget(this Task task)
{
await task;
}
Run Code Online (Sandbox Code Playgroud)
因此编程错误会引发异常并升级(通常会导致进程失效).
在具有预期(和可忽略的)异常的方法的情况下,该方法需要变得更加精细(除此之外,关于如何构建此方法的版本的任何建议将采用可接受和可忽略的异常类型的列表? )
Ste*_*ary 46
这取决于你想要的语义.如果你想确保注意到异常,那么是的,你可以await完成任务.但在那种情况下,它不是真正的"火与忘记".
一个真正的"火与忘记" - 从某种意义上说,你不关心它何时完成,或者它是成功完成还是错误 - 是非常罕见的.
编辑:
处理异常:
public static async void Forget(this Task task, params Type[] acceptableExceptions)
{
try
{
await task.ConfigureAwait(false);
}
catch (Exception ex)
{
// TODO: consider whether derived types are also acceptable.
if (!acceptableExceptions.Contains(ex.GetType()))
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我建议使用await而不是ContinueWith.ContinueWith 有一个令人惊讶的默认调度程序(如我的博客中所述),Task.Exception并将实际的异常包装在一起AggregateException,使错误处理代码更加繁琐.
| 归档时间: |
|
| 查看次数: |
20152 次 |
| 最近记录: |