i3a*_*non 18 .net c# idisposable task-parallel-library cancellation-token
我一直在看到Cancellation.Register与结果中的using子句一起使用的代码CancellationTokenRegistration:
using (CancellationTokenRegistration ctr = token.Register(() => wc.CancelAsync()))
{
await wc.DownloadStringAsync(new Uri("http://www.hamster.com"));
}
Run Code Online (Sandbox Code Playgroud)
我得到你应该确保你Dispose的IDisposable,但为什么它甚至工具IDisposable?有什么资源需要发布?它认为平等的唯一方法.
如果你不这样做Dispose会怎么样?你泄漏了什么?
nos*_*tio 16
此模式是确保CancellationTokenRegistration.Unregister()自动调用的便捷方式.它经常被Stephen Toub用于.NET博客文章的并行编程,例如这里.
我知道你应该确保你处理一个IDisposable,但为什么它甚至实现IDisposable?有什么资源需要发布?它认为平等的唯一方法.
IMO,对此的最佳答案可以在微软Mike Liddell 的.NET 4取消框架文章中找到:
当向a注册回调时,将捕获
CancellationToken当前线程,ExecutionContext以便使用完全相同的安全上下文运行回调.ct.Register()如果需要,可以通过过载来请求捕获当前线程的同步上下文是可选的.回调通常被存储,然后被要求注销时运行,但如果回调取消已要求注册后,回调将立即在当前线程上运行,或通过Send()对当前SynchronizationContext(如果适用).当回调被注册到a时
CancellationToken,返回的对象是aCancellationTokenRegistration.这是一种轻型结构类型IDiposable,并且处理此注册对象会导致取消注册回调.保证在Dispose()方法返回后,注册的回调既不运行也不随后开始.这样做的结果是CancellationTokenRegistration.Dispose()必须阻止回调当前正在执行.因此,所有已注册的回调应该是快速的,并且不会阻塞任何显着的持续时间.
Mike Liddell的另一个相关文档是"在.NET Framework 4中使用取消支持"(UsingCancellationinNET4.pdf).
更新后,这可在参考源中进行验证.
同样重要的是要注意,取消回调是注册的CancellationTokenSource,而不是CancellationToken.因此,如果CancellationTokenRegistration.Dispose()未正确确定范围,则注册将在父CancellationTokenSource对象的生命周期内保持活动状态.当异步操作的范围结束时,这可能会导致意外的回调,例如:
async Task TestAsync(WebClient wc, CancellationToken token)
{
token.Register(() => wc.CancelAsync());
await wc.DownloadStringAsync(new Uri("http://www.hamster.com"));
}
// CancellationTokenSource.Cancel() may still get called later,
// in which case wc.CancelAsync() will be invoked too
Run Code Online (Sandbox Code Playgroud)
因此,对于一次性CancellationTokenRegistration使用using(或CancellationTokenRegistration.Dispose()明确地使用try/finally)的范围是重要的.
| 归档时间: |
|
| 查看次数: |
3536 次 |
| 最近记录: |