10

条件変数とモニターはC#で使用されていますか?

誰かが私に例を教えてもらえますか?

4

5 に答える 5

14

.NETでシグナリングのためだけに使用する条件変数に相当するのは、抽象WaitHandleクラスです。その実用的な実装は、ManualResetEventクラスとAutoResetEventクラスです。

モニターとして使用する条件変数には、System.Threading.Monitorが必要です。C#lockステートメントを使用すると、非常に使いやすくなり、Exit()呼び出しを明示的にプログラミングしなくても、モニターが常に終了するようになります。

于 2009-12-31T16:50:59.817 に答える
4

System.Threading.Monitorは一方向です(内の例)

于 2009-12-31T16:41:26.400 に答える
3

Monitorクラスのシンタックスシュガーとして機能するLockオブジェクトを使用できます。

lock(someObject)
{
    // Thread safe code here.
}

http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.80%29.aspx

于 2009-12-31T16:39:39.620 に答える
2

ManualResetEventやその仲間の代わりに、Windowsは条件変数のネイティブサポートを提供するようになりました。自分でベンチマークを行ったわけではありませんが、ネイティブAPIを利用するとパフォーマンスが向上する可能性があります。

これは、C#からこの(比較的新しい)構成にアクセスする方法を説明するCodeProjectの記事です。

Vista /Server2008条件変数用の.NETラッパー

于 2011-02-08T20:18:31.013 に答える
0

このバージョンは、シグナリングを待機している間、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();
            }
        }
    }
}
于 2014-11-01T13:52:46.720 に答える