. net 4.5 Async + Await Fire and Forget潜在的内存泄漏

本文关键字:Forget 泄漏 内存 and Fire Async Await net | 更新日期: 2023-09-27 18:09:36

我在ASP中使用类似于下面的非关键的"即发即弃"操作的代码。净

private void SomeMethod()
{
    FireAndForgetAsync();
}
private async Task FireAndForgetAsync()
{
    // Simulate medium running IO blocking operation
    await Task.Delay(sleepTime).ConfigureAwait(false);
    // Simulating the rare scenario where an error occurs
    throw new Exception("An Error Occurred");
}

在异步方法返回的任务中捕获异常,这可以防止未处理的异常导致应用程序崩溃。

但是这段代码会导致内存泄漏吗?因为返回的Task(及其异常)没有被分配/访问?我的想法是,它只会被垃圾收集,除非一些。net框架代码持有对任务的引用。

. net 4.5 Async + Await Fire and Forget潜在的内存泄漏

代码中没有内存泄漏的风险。至少从您提供的代码片段中。

但是,当任务正在完成时,由于未处理的异常,您的应用程序可能被CLR终止。

如果你创建了一个Task,并且你从来没有调用Task . wait()或者尝试检索Task的结果,当Task被垃圾收集器收集时,它将在完成过程中拆除你的应用程序。有关详细信息,请参阅MSDN在TPL中的异常处理页面。

(Reed Copsey’s Answer)

有不止一个解决方案/变通方法。你可以在这篇文章中找到更多的信息:等待任务或访问其exception属性时都没有观察到Task's异常。因此,未被观察到的异常是

(正如I3arnon所提到的,这种行为在。net 4.5中改变了。)

代码中没有内存泄漏的危险。只要任务已经结束(它已经结束了),就没有什么可以阻止垃圾收集器收集它。如果执行异常数量的这些任务,可能会使用大量内存,但它们将被GCed。

如果这些任务不会结束(例如,如果它们有while (true)),或者如果您保留对它们的引用,则有内存泄漏的机会。


如评论中所述。使用"fire and forget"和async-await是非常不鼓励的。