即发即忘的方法 [英] Fire and Forget approach

查看:35
本文介绍了即发即忘的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个答案有关,

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

If I truly do want to "Fire and Forget" a method that does return a task, and (for simplicity) let's assume that the method isn't expected to throw any exceptions. I can use the extension method listed in the answer:

public static void Forget(this Task task)
{
}

使用这种方法,如果Task 的动作中存在导致抛出异常的错误,那么当抛出意外异常时,异常将被吞并不被注意.

Using this approach, if there are bugs in action of the Task that cause an exception to be thrown then when the unexpected exception is thrown, the exception will be swallowed and go unnoticed.

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

Question: Wouldn't it be more appropriate in this scenario for the extension method to be of the form:

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

因此编程错误会引发异常并升级(通常会导致进程中断).

So that programming errors throw an exception and get escalated (usually bringing down the process).

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

In the case of a method with expected (and ignorable) exceptions, the method would need to become more elaborate (as an aside, any suggestions on how to construct a version of this method that would take a list of acceptable and ignorable exception types?)

推荐答案

这取决于您想要的语义.如果您想确保注意到异常,那么是的,您可以await 任务.但在那种情况下,它并不是真正的即发即忘".

It depends on the semantics you want. If you want to ensure exceptions are noticed, then yes, you could await the task. But in that case it's not truly "fire and forget".

真正的即发即忘"——即你不关心它何时完成,或者它是否成功完成或有错误——是极其罕见的.

A true "fire and forget" - in the sense that you don't care about when it completes or whether it completes successfully or with error - is extremely rare.

用于处理异常:

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 而不是 ContinueWith.ContinueWith 有一个令人惊讶的默认调度程序(如前所述在我的博客上)和 Task.Exception 会将实际异常包装在 AggregateException 中,使错误处理代码更加繁琐.

Note that I recommend using await instead of ContinueWith. ContinueWith has a surprising default scheduler (as noted on my blog) and Task.Exception will wrap the actual exception in an AggregateException, making the error handling code more cumbersome.

这篇关于即发即忘的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆