为了账号安全,请及时绑定邮箱和手机立即绑定

一劳永逸的方法

一劳永逸的方法

C#
慕盖茨4494581 2019-10-29 14:46:51
如果我确实确实想“触发并忘记”一个确实返回任务的方法,并且(为简单起见),我们假设该方法不会引发任何异常。我可以使用答案中列出的扩展方法:public static void Forget(this Task task){}使用这种方法,如果存在运行中的错误,这些错误Task会导致引发异常,那么当引发意外的异常时,该异常将被吞没并且不会被注意到。问题:在这种情况下,扩展方法采用以下形式更合适吗:public static async void Forget(this Task task){    await task;}这样编程错误会引发异常并逐步升级(通常会降低进程)。对于具有预期(和可忽略)异常的方法,该方法将需要变得更加复杂(顺便说一句,有关如何构造此方法的版本的建议,其中将采用可接受和可忽略的异常类型列表)? )
查看完整描述

3 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

这取决于您想要的语义。如果您想确保注意到异常,那么可以,您可以执行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而不是ContinueWith。ContinueWith 有一个令人惊讶的默认调度程序(如我的博客所述),Task.Exception并将实际的异常包装在中AggregateException,使错误处理代码更加繁琐。


查看完整回答
反对 回复 2019-10-29
?
MMTTMM

TA贡献1869条经验 获得超4个赞

是的,如果您对任务是否引发异常感兴趣,那么您将需要await结果,但另一方面,这几乎违背了“解雇 ” 的目的。


在您想知道是否发生不好的情况下,建议的执行方法是使用延续,例如


public static void ForgetOrThrow(this Task task)

{

    task.ContinueWith((t) => {

        Console.WriteLine(t.Exception);

    }, TaskContinuationOptions.OnlyOnFaulted);

}


查看完整回答
反对 回复 2019-10-29
  • 3 回答
  • 0 关注
  • 543 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信