Yur*_* S. 10 c# error-handling asynchronous async-ctp .net-4.5
由于各种原因,包含在.NET 4.5和Async CTP 4.0 中等待的流可能会卡住,例如,因为远程客户端没有响应.当然,WaitForAny,当我们等待一些超时任务时,是一个明显的解决方案,用于恢复高级流程.但是,这并没有解决所有可能的问题.
我有以下问题:
等待的环境会发生什么变化?据我所知,这会造成内存泄漏.我对吗?
如何检查调试器或使用相应的API 在应用程序中存在多少悬空" awaiter "?
是否可以在全球范围内枚举它们?
如果3.是正确的,是否可以强制取消这些*await*s 的任务(即清理)?
注意:在问题4中,我不询问在显式创建任务期间要使用的取消项目.我指的是间接创建任务的情况:
async Task<bool> SomeTask()
{
await Something();
...
return true;
}
Run Code Online (Sandbox Code Playgroud)
这个问题的动机:
1等待的环境会发生什么变化?
我相信它会导致内存泄漏(如果你await正在进行I/O操作).最好总是完成你Task的(这意味着你的async方法迟早会回来).
从svick的评论更新:有些情况下这不会导致内存泄漏.
2如何在调试器中或使用相应的API检查应用程序中存在多少悬空"awaiter"?
我不确定是否有一种简单的方法可以做到这一点.我相信应该可以编写一个调试器插件,它使用SoS来查找与编译器生成的异步状态机模式匹配的现有堆对象.
但是,这是一个很大的一点好处的工作.
3是否可以在全球范围内枚举它们?
不是普通的API.
如果3是正确的,是否可以强制取消这些等待的任务(即清理)?
即使您可以在运行时枚举它们(例如,通过分析API),也不能"强制"取消任务.取消是合作的.
处理此问题的正确方法是使用标准取消.基于任务的异步模式文档指定了可取消async方法的准则.
在最低级别:asyncBCL中的许多API都是可选的CancellationToken.
在中间层:让async方法采用可选方法并将其CancellationToken传递给其他async方法是很常见的.
在最高级别:在给定时间之后创建一个CancellationToken会触发的很容易.
关于问题2和3我没有真正的答案。
拥有一去不复返的任务绝不是一件好事。为了避免这种情况并回答第 4 点:任务可以取消。
您需要创建一个传递给任务的取消令牌。该任务自行负责监视取消令牌的状态,并在取消时抛出异常。(也可以使用相同的令牌一次取消多个任务。)
MSDN 上的这篇文章向您展示了如何执行此操作。
| 归档时间: |
|
| 查看次数: |
3559 次 |
| 最近记录: |