gpt4 book ai didi

c# - 异步编程中的悬挂等待和可能的内存泄漏

转载 作者:可可西里 更新时间:2023-11-01 09:09:04 25 4
gpt4 key购买 nike

.NET 4.5 和 Async CTP 4.0 中包含 await 的流程可能会由于各种原因而卡住,例如因为远程客户端没有响应。当然,WaitForAny,当我们也等待某个超时任务时,显然是一种恢复高层流的解决方案。尽管如此,这并不能解决所有可能的问题。

我有以下问题:

  1. 永远不会返回的 await 的上下文会发生什么?我知道这会造成内存泄漏。我说得对吗?

  2. 我如何在调试器中或使用相应的 API 检查应用程序中存在多少悬挂“等待者”?

  3. 是否可以全局枚举它们?

  4. 如果 3. 是正确的,是否可以强制取消这些 *await*s 的任务(即清理)?

注意:在问题 4 中,我没有询问在显式任务创建期间要使用的取消项。我指的是间接创建任务的情况:

async Task<bool> SomeTask()
{
await Something();
...
return true;
}

这个问题的动机:

  1. 尽量避免内存泄漏
  2. 试图用太多涉及取消 token 的情况使代码复杂化
  3. 在许多情况下,每个低级任务的超时时间事先并不知道,但高级流程可以使用恢复方法:“我们被卡住了?没关系,只是清理一下,让我们重新开始”。

最佳答案

1 What happens to the context of await which does not ever return?

我相信它会导致内存泄漏(如果您正在await进行 I/O 操作)。最好always complete your Tasks (这意味着您的 async 方法迟早会返回)。

根据 svick 的评论更新:situations不会导致内存泄漏。

2 How can I check either in debugger or using the respective API how many dangling "awaiter"s exist in the application?

我不确定是否有一种简单的方法可以做到这一点。我相信应该可以编写一个使用 SoS 的调试器插件来查找与编译器生成的异步状态机模式相匹配的现有堆对象。

但这是一个很多的工作,收效甚微。

3 Is it possible to enumerate them globally?

不适用于普通 API。

If 3 is correct, is it possible to force cancellation the tasks for these awaits (i.e. to clean up)?

即使您可以在运行时枚举它们(例如,通过性能分析 API),您也不能“强制”取消任务。取消是合作的。


处理此问题的正确方法是使用标准取消。 Task-based Asynchronous Pattern document指定可取消的 async 方法的指南。

在最低级别:BCL 中的许多 async API 都采用可选的 CancellationToken

在中层:async 方法采用可选的 CancellationToken 并将其传递给其他 async 方法是很常见的。

在最高级别:它是 easy to create将在给定时间后触发的 CancellationToken

关于c# - 异步编程中的悬挂等待和可能的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12953377/

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