2015-09-25 32 views
6

可以说你有一个服务API调用。被调用者在某种程度上性能至关重要,因此为了不超过必要的API调用时间,使用了一种SaveAsync()方法。然而,我不能await它,因为这会阻止API调用的时间与非异步版本一样长(或者甚至更长)。您是否需要等待异步方法?

我问原因是这样的:如果你await电话,有没有Task对象返回被垃圾回收的机会吗?如果是这样,那会中断正在运行的任务吗?

+0

你能表现出位的代码,其中你会等待这种方法? –

+1

你确定等待会持有API吗?据我所知,等待点将被存储在空间块,当结果会来CLR将处理您的代码 –

回答

6

我问的原因是这样的:如果你不等待这个调用,那么Task对象返回的机会是否会被垃圾回收?

一般情况下,不应该发生。对任务进行排队的底层TaskScheduler通常会在所需的生命周期内保持对其的引用,直到完成为止。你可以看到,TaskScheduler.QueueTask文档中:

典型的实现将任务存储在内部数据结构,这将让将在未来一段时间内执行这些任务的线程提供服务。

你真正的问题是将与ASP.NET SynchronizationContext一起使用,它跟踪运行时正在进行的异步操作。如果您的控制器操作在异步操作之前完成,您将会遇到异常。

如果你想拥有“射后不理”在ASP.NET操作,你应该确保与ASP.NET运行时注册它们,或者通过HostingEnvironment.QueueBackgroundWorkItemBackgroundTaskManager

+0

的一部分幸运的是,这是托管在Windows服务,而不是在asp.net。但对于任何想在asp.net中这样做的人来说,这都是很好的信息。 – Alex

2

不,它不会中断正在运行的任务,但是您也不会观察任务中的异常,这并不是很好。您可以(至少部分)避免将所有正在运行的代码包装在try ... catch中并记录异常。另外,如果你在asp.net里面,那么你的整个应用程序可能会被停止或回收,并且在这个的情况下你的任务会被中断。这很难避免 - 您可以注册AppPool关闭通知,或者使用类似Hangfire的东西。