C # lock and listen to CancellationToken

I want to use lock or similar synchronization to protect a critical section. At the same time, I want to listen to the CancellationToken.

Now I use a mutex like this, but a mutex does not have such good performance. Can I use any of the other synchronization classes (including the new .Net 4.0) instead of the mutex?

WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex}); CancelToken.ThrowIfCancellationRequested(); 
+8
multithreading c # task-parallel-library
source share
3 answers

Take a look at the new .NET 4.0 Framework SemaphoreSlim class feature. It provides the SemaphoreSlim.Wait (CancellationToken) method.

Blocks the current thread until it can enter SemaphoreSlim, while enforcing the CancellationToken

From a certain point of view, using Semaphore in such a simple case can be overhead, since it was originally intended to provide access for multiple threads, but you might find it useful.

EDIT: code snippet

 CancellationToken token = new CancellationToken(); SemaphoreSlim semaphore = new SemaphoreSlim(1,1); try { // block section entrance for other threads semaphore.Wait(token); // critical section code // ... if (token.IsCancellationRequested) { // ... } } finally { semaphore.Release(); } 
+11
source share
 private object _lockObject = new object(); lock (_lockObject) { // critical section using (token.Register(() => token.ThrowIfCancellationRequested()) { // Do something that might need cancelling. } } 

Calling Cancel() on the token will result in a call to ThrowIfCancellationRequested() , as this was due to the Register callback. You can put any undo logic you want here. This approach is great because you can unblock calls by forcing conditions that will cause the call to end.

ThrowIfCancellationRequested throws an OperationCanceledException. You need to handle this in the calling thread, or the whole process may be killed. An easy way to do this is to start your task using the Task class, which will combine all the exceptions for you to handle the calling thread.

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

Some good things here covering co-cancellation

0
source share

you can use the Monitor object to slightly improve performance, as indicated on MSDN:

Despite the fact that the mutex can be used to synchronize threads within a process, Monitor is usually used, since monitors were developed specifically for the .NET Framework and therefore use resources better

For more information

http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx

CancellationToken offers you a model for canceling asynchronous or long synchronous operations together. if you want to use it with a monitor class, you need to structure the code to release the lock if it is a cancellation request. You can do something below:

  public void ThreadSafeMethod() { var cancellationToken=new CancellationToken(); object locker=new object(); Monitor.Enter(locker); try { //your code if (token.IsCancellationRequested) { Monitor.Exit(locker); } } finally { Monitor.Exit(locker); } } 

or if you want to use ThrowIfCancellationRequested:

  public void ThreadSafeMethod() { var cancellationToken=new CancellationToken(); object locker=new object(); Monitor.Enter(locker); try { //your code cancellationToken.ThrowIfCancellationRequested(); } catch(OperationCanceledException) { } finally { Monitor.Exit(locker); } } 
-2
source share

All Articles