何时处置 CancellationTokenSource? [英] When to dispose CancellationTokenSource?
问题描述
CancellationTokenSource
类是一次性的.快速查看 Reflector 可以证明 KernelEvent
的使用,这是一种(很可能)非托管资源.由于CancellationTokenSource
没有finalizer,如果我们不处理它,GC就不会处理.
The class CancellationTokenSource
is disposable. A quick look in Reflector proves usage of KernelEvent
, a (very likely) unmanaged resource.
Since CancellationTokenSource
has no finalizer, if we do not dispose it, the GC won't do it.
另一方面,如果您查看 MSDN 文章中列出的示例 托管线程中的取消,只有一个代码片段处理令牌.
On the other hand, if you look at the samples listed on the MSDN article Cancellation in Managed Threads, only one code snippet disposes of the token.
在代码中处理它的正确方法是什么?
What is the proper way to dispose of it in code?
- 如果不等待,则无法使用
using
包装启动并行任务的代码.只有在您不等待的情况下取消才有意义. - 当然,您可以使用
Dispose
调用在任务上添加ContinueWith
,但这是要走的路吗? - 可取消的 PLINQ 查询如何处理,这些查询不会同步回来,而只是在最后做一些事情?假设
.ForAll(x => Console.Write(x))
? - 它可以重复使用吗?同一个token可以用于多次调用,然后和宿主组件一起配置,比如说UI控件?
- You cannot wrap code starting your parallel task with
using
if you do not wait for it. And it makes sense to have cancellation only if you do not wait. - Of course you can add
ContinueWith
on task with aDispose
call, but is that the way to go? - What about cancelable PLINQ queries, which do not synchronize back, but just do something at the end? Let's say
.ForAll(x => Console.Write(x))
? - Is it reusable? Can the same token be used for several calls and then dispose it together with the host component, let's say UI control?
因为它没有类似 Reset
的方法来清理 IsCancelRequested
和 Token
字段,所以我认为它不可重用,因此每次启动任务(或 PLINQ 查询)时,都应该创建一个新任务.这是真的吗?如果是,我的问题是在那些许多 CancellationTokenSource
实例上处理 Dispose
的正确和推荐策略是什么?
Because it does not have something like a Reset
method to clean-up IsCancelRequested
and Token
field I would suppose it's not reusable, thus every time you start a task (or a PLINQ query) you should create a new one. Is it true? If yes, my question is what is the correct and recommended strategy to deal with Dispose
on those many CancellationTokenSource
instances?
推荐答案
说到是否真的有必要在 CancellationTokenSource
上调用 Dispose... 我的项目中有内存泄漏,结果证明CancellationTokenSource
是问题所在.
Speaking about whether it's really necessary to call Dispose on CancellationTokenSource
... I had a memory leak in my project and it turned out that CancellationTokenSource
was the problem.
我的项目有一个服务,它不断读取数据库并触发不同的任务,并且我正在将链接的取消令牌传递给我的工作人员,因此即使他们完成处理数据,也没有处理取消令牌,这导致了内存泄漏.
My project has a service, that is constantly reading database and fires off different tasks, and I was passing linked cancellation tokens to my workers, so even after they had finished processing data, cancellation tokens weren't disposed, which caused a memory leak.
MSDN 托管线程中的取消 明确指出:
MSDN Cancellation in Managed Threads states it clearly:
请注意,完成后必须在链接的令牌源上调用 Dispose
.有关更完整的示例,请参阅 如何:侦听多个取消请求.
Notice that you must call
Dispose
on the linked token source when you are done with it. For a more complete example, see How to: Listen for Multiple Cancellation Requests.
我在实现中使用了 ContinueWith
.
这篇关于何时处置 CancellationTokenSource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!