c# 锁定并监听CancellationToken
我想使用锁或类似的同步来保护关键部分。同时我想听一个CancellationToken。
现在我正在使用这样的互斥体,但是互斥体没有那么好的性能。我可以使用任何其他同步类(包括新的 .Net 4.0)来代替互斥体吗?
WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex});
CancelToken.ThrowIfCancellationRequested();
I want to use lock or a similar synchronization to protect a critical section. At the same time I want to listen to a CancellationToken.
Right now I'm using a mutex like this, but mutex doesn't have as good performance. Can I use any of other synchronization classes (including the new .Net 4.0) instead of the mutex?
WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex});
CancelToken.ThrowIfCancellationRequested();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
了解新的
.NET 4.0 Framework
功能 SemaphoreSlim 类。它提供了 SemaphoreSlim.Wait(CancellationToken) 方法。从某些角度来看,在如此简单的情况下使用 Semaphore 可能会产生开销,因为最初它的设计目的是为多个线程提供访问,但也许您可能会发现它很有用。
编辑:代码片段
Take a look at the new
.NET 4.0 Framework
feature SemaphoreSlim Class. It provides SemaphoreSlim.Wait(CancellationToken) method.From some point of view using Semaphore in such simple case could be an overhead because initially it was designed to provide an access for multiple threads, but perhaps you might find it useful.
EDIT: The code snippet
对令牌调用
Cancel()
将导致调用ThrowIfCancellationRequested()
,因为它与Register
回调挂钩。您可以将任何您想要的取消逻辑放在这里。这种方法很棒,因为您可以通过强制执行导致调用完成的条件来取消阻塞调用。ThrowIfCancellationRequested 抛出一个OperationCanceledException。您需要在调用线程上处理此问题,否则整个进程可能会崩溃。执行此操作的一个简单方法是使用 Task 类启动任务,该类将聚合所有异常以供您在调用线程上处理。
这里介绍了合作取消的一些好东西
Calling
Cancel()
on a token will result in theThrowIfCancellationRequested()
being invoked as that was what is hooked up to theRegister
callback. You can put whatever cancellation logic you want in here. This approach is great because you can cancel blocking calls by forcing the conditions that will cause the call to complete.ThrowIfCancellationRequested throws a OperationCanceledException. You need to handle this on the calling thread or your whole process could be brought down. A simple way of doing this is by starting your task using the Task class which will aggregate all the exceptions up for you to handle on the calling thread.
Some good stuff here covering co-operative cancellation
您可以使用带有超时的
Monitor.TryEnter
来等待锁定并定期检查是否取消。请注意,我不会在高争用情况下建议这样做,因为它会影响性能。我将使用它作为防止死锁的安全机制,以防您无法使用
SemaphoreSlim
,因为它与Monitor.Enter
具有不同的相同线程重入语义。返回true后,必须使用
Monitor.Exit
释放对syncObject的锁定。You can use
Monitor.TryEnter
with timeout to wait for the lock and check periodically for cancellation.Note that I would not recommend this in high contention situations as it can impact performance. I would use it as a safety mechanism against deadlocks in case you cannot use
SemaphoreSlim
as it has different same thread re-entrancy semantics thanMonitor.Enter
.After returning true, lock on syncObject has to be released using
Monitor.Exit
.