你必须等待异步方法吗?

7
假设您有一个服务API调用。被调用方在某种程度上是性能关键的,因此为了不比必要的时间更长地挂起API调用,会使用SaveAsync()方法。然而,我不能await它,因为那样会和非异步版本一样挂起API调用,甚至可能更长。
我问这个问题的原因是:如果您不await调用,返回的Task对象是否有可能被垃圾收集?如果是这样,是否会中断正在运行的任务?

你能展示一些代码,在其中等待这个方法吗? - Matteo Umili
1
你确定 await 会暂停 API 吗?据我所知,await 点将被存储在特殊块中,当结果出现时,CLR 将处理你的 await 代码部分。 - Oleh Dokuka
2个回答

7
我询问的原因是:如果您不等待调用,返回的Task对象是否有可能被垃圾回收?
一般来说,不会发生这种情况。通常排队任务的底层TaskScheduler会保留对它的引用直到它完成所需的生命周期。您可以在TaskScheduler.QueueTask的文档中看到这一点:
“典型的实现将任务存储在内部数据结构中,该数据结构由稍后执行这些任务的线程服务。”
您真正的问题将在于ASP.NET同步上下文,在运行时跟踪任何正在进行的异步操作。如果控制器操作在异步操作之前完成,则会出现异常。
如果您想在ASP.NET中拥有"fire and forget"操作,应确保通过HostingEnvironment.QueueBackgroundWorkItem或BackgroundTaskManager将其注册到ASP.NET运行时。

幸运的是,这是托管在Windows服务中而不是ASP.NET中。但对于任何想在ASP.NET中执行此操作的人来说,这是一个好消息。 - Alex

2
不会中断正在运行的任务,但你也无法观察到任务中的异常,这并不是很好。你可以通过将所有正在运行的代码包装在 try...catch 中并记录异常(至少部分地)避免这种情况。
此外,如果你正在 asp.net 中运行,那么整个应用程序可能会停止或重启,在这种情况下,你的任务将被中断。要解决这个问题比较困难-你可以注册 AppPool 关闭通知,或使用类似于 Hangfire 的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接