条件変数とモニターはC#で使用されていますか?
誰かが私に例を教えてもらえますか?
.NETでシグナリングのためだけに使用する条件変数に相当するのは、抽象WaitHandleクラスです。その実用的な実装は、ManualResetEventクラスとAutoResetEventクラスです。
モニターとして使用する条件変数には、System.Threading.Monitorが必要です。C#lock
ステートメントを使用すると、非常に使いやすくなり、Exit()呼び出しを明示的にプログラミングしなくても、モニターが常に終了するようになります。
System.Threading.Monitorは一方向です(内の例)
Monitorクラスのシンタックスシュガーとして機能するLockオブジェクトを使用できます。
lock(someObject)
{
// Thread safe code here.
}
http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.80%29.aspx
ManualResetEventやその仲間の代わりに、Windowsは条件変数のネイティブサポートを提供するようになりました。自分でベンチマークを行ったわけではありませんが、ネイティブAPIを利用するとパフォーマンスが向上する可能性があります。
これは、C#からこの(比較的新しい)構成にアクセスする方法を説明するCodeProjectの記事です。
このバージョンは、シグナリングを待機している間、MutexまたはReaderWriterLockSlimのロックを解除し、戻る前に再ロックします。これは、posixの方法です。
using System.Collections.Concurrent;
namespace System.Threading.More {
public class ConditionVariable {
private readonly ConcurrentQueue<ManualResetEventSlim> _waitingThreads = new ConcurrentQueue<ManualResetEventSlim>();
/// <summary>
/// Atomically unlocks and waits for a signal.
/// Then relocks the mutex before returning
/// </summary>
/// <param name="mutex"></param>
public void Wait(Mutex mutex) {
if (mutex == null) {
throw new ArgumentNullException("mutex");
}
var waitHandle = new ManualResetEventSlim();
try {
_waitingThreads.Enqueue(waitHandle);
mutex.ReleaseMutex();
waitHandle.Wait();
} finally {
waitHandle.Dispose();
}
mutex.WaitOne();
}
public void WaitRead(ReaderWriterLockSlim readerWriterLock) {
if (readerWriterLock == null) {
throw new ArgumentNullException("readerWriterLock");
}
var waitHandle = new ManualResetEventSlim();
try {
_waitingThreads.Enqueue(waitHandle);
readerWriterLock.ExitReadLock();
waitHandle.Wait();
} finally {
waitHandle.Dispose();
}
readerWriterLock.EnterReadLock();
}
public void Signal() {
ManualResetEventSlim waitHandle;
if (_waitingThreads.TryDequeue(out waitHandle)) {
waitHandle.Set();
}
}
public void Broadcast() {
ManualResetEventSlim waitHandle;
while (_waitingThreads.TryDequeue(out waitHandle)) {
waitHandle.Set();
}
}
}
}