English 中文(简体)
AutoResetEvent, ManualResetEvent vs Monitor
原标题:

Lets say I have to orchestrate a synchronization algorithm in .Net 3.5 SP1 and any of the synchronization primitives listed in the title fit perfectly for the task.

From a performance perspective, is any single one of those more performant than the others?

I ask this because I have been coding for a while now, but without proper knowledge on the subject.

最佳回答

If you can, go with Monitor. It s similar to a CRITICAL_SECTION. AutoResetEvent/ManualResetEvent might have slightly more overhead, since these can be shared by different processes, whereas a Monitor belongs to a single process.

问题回答

WaitHandles look very similar to Wait/Pulse Constructs, but the difference is in detail: The WaitHandles Set method, sets the Signal even if no thread is waiting. This means if you call Set in a thread and then call WaitOne in another thread on the same waithandle afterwards, the second thread will continue. Wait and Pulse are different, Pulse only signals a thread that is already in the waiting queue. This means if you call Pulse in a thread and then call Wait in another thread on the same object afterwards, the second thread will wait forever (deadlock). You ve got to be extremely carefull if using Wait and Pulse, only use it if you know what you are doing otherwise you might just be lucky...

To create the behaviour of a WaitHandle yourself using Monitor, weather AutoReset or ManualReset, you ve got to do way more than a simple Wait/Pulse Construct. Just use the Tools you need to get the Job done:

If you can t synchronize threads with simple locking or atomic operations, think of using WaitHandles. If you can t synchronize threads with WaitHandles, think of using Wait and Pulse.

Wait and pulse are fine, if you follow some simple rules:

  1. You may not bother to lock if if locking isn t needed for your object and you can tell in advance that it s ready; if, however, it looks like you ll have to wait, you must acquire the lock and then make certain you still really do have to wait before you actually do it; you should also in most cases assume that you may randomly be woken up whether or not conditions are ready, so you should recheck the conditions every time you wake up and re-wait if needed.
  2. A pulse must be given after conditions have been set up that will allow waiting code to continue.
  3. If you have something like a "quit" flag, it may be helpful to have every piece of code that acquires the lock test the quit flag after releasing the lock and, if the flag is set, reacquire the lock and send a pulse. You could then have a quit routine set the flag, try acquiring the lock with zero timeout, and send a pulse only if the lock could be acquired. If the acquisition failed, you could be assured some other piece of code will send the necessary pulse. This will avoid any possibility of the quit routine getting stuck at the lock.




相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签