如果我不等待任务会怎样?

enz*_*nzi 28 c# async-await

考虑这个例子:

var task = DoSomething()
bool ready = await DoSomethingElse();
if (!ready) 
  return null;

var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
Run Code Online (Sandbox Code Playgroud)

DoSomething做一些可能需要一段时间的非常重要的工作,因此我们首先开始它.
与此同时,我们检查我们是否准备就绪,DoSomethingElse如果没有,我们会提前退出.
我们DoThirdThing 只有在我们这样做时才会打电话ready,因为宇宙可能会爆炸.

我们不能用Task.WhenAll作为DoThirdThing依赖DoSomethingElse,我们也不想等待DoSomething,因为我们希望尽可能地其他两种方法同时调用.

问题:发生什么task,如果我们不能ready和退出早?

它抛出的任何异常会被重新抛出SynchronizationContext吗?
如果task正常完成会有问题吗,因为没有人消耗它的价值?

后续行动:有没有一种简洁的方法可以确保task等待?

我们可以简单地说,await task如果我们不是ready,但如果有50个退出条件,这将是非常繁琐的.
可以使用finally块来await task重新抛出潜在的异常吗?如果task正常完成,将在finally块中再次等待,但这不应该导致任何问题?

Ste*_*ary 20

问题是:如果我们还没准备好并提前退出,会发生什么?

没有.代码忽略任务,因此忽略该任务.

它会抛出的任何异常会被SynchronizationContext重新抛出吗?

不会.他们会(最终)被传递TaskScheduler.UnobservedTaskException然后被忽略.

如果任务正常完成,是否存在问题,因为没有人消耗它的值?

不.

后续行动:有没有一种巧妙的方法来确保等待任务?

没有.

可以使用finally块来等待任务并重新抛出潜在的异常吗?

是的,如果您的代码实际上await是任务.据推测,这意味着在某处保存任务.

如果任务正常完成,则会在finally块中再次等待,但这不会导致任何问题吗?

您可以await根据需要多次执行任务.

如果我们还没准备好,我们可以简单地等待任务,但是如果有50个退出条件,那将非常繁琐.

然后考虑重组代码.

  • @enzi:这完全取决于您的应用程序逻辑。如果操作是可以忽略的,那么它可以忽略。如果没有,那么它不应该被忽略。 (2认同)
  • 请注意,您可以根据需要多次等待“任务”。但是,“ValueTask”只能等待一次。 (2认同)