一尘不染

一劳永逸的方法

c#

这个答案有关

如果我确实确实想“触发并忘记”一个确实返回任务的方法,并且(为简单起见),我们假定该方法不会引发任何异常。我可以使用答案中列出的扩展方法:

public static void Forget(this Task task)
{
}

使用这种方法,如果存在运行中的错误,这些错误Task会导致引发异常,则当引发意外异常时,该异常将被吞没且不会被注意到。

问题: 在这种情况下,扩展方法采用以下形式更合适吗:

public static async void Forget(this Task task)
{
    await task;
}

这样编程错误会引发异常并逐步升级(通常会降低进程)。

对于具有预期(和可忽略)异常的方法,该方法将需要变得更加复杂(顺便说一句,关于如何构造该方法的版本的建议,该版本将采用可接受和可忽略的异常类型列表? )


阅读 533

收藏
2020-05-19

共1个答案

一尘不染

这取决于您想要的语义。如果您想确保注意到异常,那么可以,您可以执行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;
  }
}

请注意,我建议使用await而不是ContinueWithContinueWith
有一个令人惊讶的默认调度程序(如我的博客所述),Task.Exception并将实际的异常包装在中AggregateException,使错误处理代码更加繁琐。

2020-05-19