发射后不管的做法 [英] Fire and Forget approach

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

问题描述

这个答案相关,

如果我真的不希望发射后不管,它返回一个任务的方法,和(为简单起见),我们假设该方法预计不会引发任何异常。我可以使用在回答中列出的扩展方法:

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)
{
}

使用这种方法,如果有在工作导致异常时则抛出时,意外抛出异常的动作错误,异常会被吞入,并被忽视。

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?)

推荐答案

这取决于你想要的语义。如果你想确保异常发现,那么,你可以等待的任务。但是,在这种情况下,它不是真正的射后不理。

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 ,使得错误处理code更麻烦。

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天全站免登陆