gpt4 book ai didi

c# - Task.Delay.ContinueWith 和使用 Task.Delay 进行异步等待之间有什么区别(如果有)?

转载 作者:行者123 更新时间:2023-12-02 03:35:10 27 4
gpt4 key购买 nike

这是一个 linqpad 示例,展示了在短暂延迟后异步执行方法的两种方法。这两个例子似乎做了完全相同的事情。我通常会实现第一个版本(使用 Task.Delay.ContinueWith),但我也看到使用了第二个实现(异步等待)。这两种实现之间有什么区别吗?此场景的工作 Linqpad 示例:

void Main()
{
// Using Task.Delay.ContinueWith...
Task.Delay(1000).ContinueWith(t => DoSomething());

// ... vs async await. Note that I'm not awaiting the task here
DoSomethingAsync();
}

public void DoSomething()
{
"Doing Something...".Dump();
}

public async Task DoSomethingAsync()
{
await Task.Delay(1000);

"Doing Something...".Dump();
}

读完这篇博文后https://blogs.msdn.microsoft.com/pfxteam/2012/03/24/should-i-expose-asynchronous-wrappers-for-synchronous-methods/我认为第一个实现是“正确的”实现,因为“DoSomethingAsync()”实际上只是将该方法卸载到线程池,并且博客文章指出:

“异步方法不应纯粹出于卸载的目的而公开:同步方法的使用者可以使用专门针对异步使用同步方法的功能(例如 Task.Run)轻松实现这种好处。”

但是,StackOverflow 上的这个答案提出了第二种解决方案:

Delay then execute Task

这两种实现之间有什么实际区别吗?如果“async wait”实现也是有效的(或者甚至更正确),那么应该如何处理返回的任务?我真的不想等待它,这是一个即发即忘的操作,但我也想处理可能引发的任何异常。

在第一个实现中,我知道我可以使用ContinueWith、OnlyOnFaulted 来处理异常。

最佳答案

它们很相似,但并不完全相同。例如,在 SynchronizationContext.Current 之前,async 方法的延续将被调度到此同步上下文,但 ContinueWith 不会,并且会在线程池线程上运行。尽管使用 ContinueWith 的另一个重载,您可以使其执行相同的操作:

.ContinueWith(t => DoSomething(), TaskScheduler.FromCurrentSynchronizationContext());

并且您可以使用 await yourTask.ConfigureAwait(false) 来阻止调度到异步版本中的同步上下文。

那么,异常处理就不同了。在async版本中,异常将直接抛出,如果有多个异常(例如来自await Task.WhenAll) - 仅第一个将被抛出,其余的将被抛出吞下去了。很难错过这个异常。

ContinueWith版本中,抛出的异常由t.Exception表示,并且它始终是AggregateException,因此您必须将其解包。另一方面 - 所有异常都存在(如果有多个)并且没有一个被吞掉。然而,很容易忘记处理该异常。例如,在您问题的代码中 - 您不会在 ContinueWith 中处理异常,因此无论是否存在异常,DoSomething() 继续都会执行。在async版本中,如果出现异常,则不会执行延续。

两种实现都是“有效的”。您不应该忘记在这两种情况下处理异常。使用ContinueWith - 要么始终检查t.Exception,要么使用OnlyOnFaulted安排单独的继续(并且仅在那里检查)。如果是 async 版本 - 将正文包装在 try-catch block 中。根据即发即忘的本质 - 您无法在调用站点处理异常,但您不应该完全放弃它们。

在短延迟后执行方法的特定情况下,我想说这只是一个偏好问题(除了捕获同步上下文方面的差异)。我个人更喜欢 ContinueWith,它更清晰地表达意图,并且您不需要语义不明确的单独方法。

关于c# - Task.Delay.ContinueWith 和使用 Task.Delay 进行异步等待之间有什么区别(如果有)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50463192/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com