c#锁定并收听CancellationToken

c#锁定并收听CancellationToken,c#,multithreading,.net-4.0,task-parallel-library,cancellation-token,C#,Multithreading,.net 4.0,Task Parallel Library,Cancellation Token,我想使用锁或类似的同步来保护关键部分。同时我想听听CancellationToken 现在我使用的是这样的互斥体,但互斥体的性能没有这么好。我可以使用任何其他同步类(包括新的.NET4.0)而不是互斥对象吗 WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex}); CancelToken.ThrowIfCancellationRequested(); 看看新的.NET4.0框架功能。它提供了一种方法 阻止当前线程,直到它可以进入信

我想使用锁或类似的同步来保护关键部分。同时我想听听CancellationToken

现在我使用的是这样的互斥体,但互斥体的性能没有这么好。我可以使用任何其他同步类(包括新的.NET4.0)而不是互斥对象吗

WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex});
CancelToken.ThrowIfCancellationRequested();

看看新的
.NET4.0框架
功能。它提供了一种方法

阻止当前线程,直到它可以进入信号量LIM,而 观察取消令牌

从某种角度来看,在这种简单的情况下使用信号量可能会造成开销,因为最初它是为多个线程提供访问而设计的,但您可能会发现它很有用

编辑:代码片段

CancellationToken token = new CancellationToken();            
SemaphoreSlim semaphore = new SemaphoreSlim(1,1);
bool tokenCanceled = false;

try {
   try {
      // block section entrance for other threads
      semaphore.Wait(token);
   }
   catch (OperationCanceledException) {
      // The token was canceled and the semaphore was NOT entered...
      tokenCanceled = true;
   }
   // critical section code
   // ...
   if (token.IsCancellationRequested)
   {
       // ...
   }
}
finally { 
   if (!tokenCanceled)
      semaphore.Release();
}
对令牌调用
Cancel()
将导致调用
ThrowIfCancellationRequested()
,因为这是连接到
寄存器的回调。你可以把你想要的任何取消逻辑放在这里。这种方法很好,因为您可以通过强制执行将导致调用完成的条件来取消阻塞调用

ThrowIfCancellationRequested引发OperationCanceledException。您需要在调用线程上处理此问题,否则整个过程可能会中断。一种简单的方法是使用task类启动任务,该类将聚合所有异常,供您在调用线程上处理

try
{
   var t = new Task(() => LongRunningMethod());
   t.Start();
   t.Wait();
}
catch (AggregateException ex)
{
   ex.Handle(x => true); // this effectively swallows any exceptions
}

一些关于合作取消的好东西

你能发布一些代码来显示关键部分以及你目前是如何释放互斥的吗?请最后尝试一下:-)@xanatos:你是说有例外吗?这是一段伪代码,用于演示信号量LIM如何与CancellationToken绑定,而不仅仅是:)@xanatos。。。为什么不自己做呢?@sll。。。不,您应该这样做,以确保不管发生什么情况,信号量都被释放what@CarstenKönig:感谢您对代码片段进行增强!如果您指的是OperationCanceledException,那么这是通过设计实现的——这是ThrowIfCancellationRequested方法抛出的。你应该处理好它,对来电者使用建议的模式(更新答案)。对你的陈述你的陈述你的陈述你的陈述你的陈述你的陈述你的陈述你的调用
取消(
取消(
取消(取消(C)对你的调用你应该处理你应该处理你应该处理你的来电者使用建议的模式(更新答案)。关于你的陈述你的声明你的调用你的调用你的调用你你的代码>对你的声明你的调用<调用<代码>对你的你的声明你的调用<调用<代码>对你的声明你的你的一个t,你你你的a a a a a a a a a a t,o,o o o o o o o o o o o o,o,o,o,o o,o,o,o,o,o,o,o,o,o,k,k,k,k,k,k,818; e̲将导致调用
ThrowIfCancellationRequested()
“。。。可以使用重载来控制此行为。
try
{
   var t = new Task(() => LongRunningMethod());
   t.Start();
   t.Wait();
}
catch (AggregateException ex)
{
   ex.Handle(x => true); // this effectively swallows any exceptions
}