开发者

Condition variables in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the qu开发者_如何学JAVAestion so it focuses on one problem only by editing this post.

Closed 6 years ago.

Improve this question

Are condition variables & monitors used in C#?

Can someone give me an example?


The equivalent of a condition variable that you use just for signaling in .NET is the abstract WaitHandle class. Practical implementations of it are the ManualResetEvent and AutoResetEvent classes.

A condition variable that you use as a monitor requires System.Threading.Monitor. The C# lock statement makes it very easy to use, it ensures the monitor is always exited without explicitly programming the Exit() call.


System.Threading.Monitor is one way (example within)


You can use the Lock object which acts as syntactic sugar for the Monitor class.

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

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


As an alternative to ManualResetEvent and friends, Windows now provides native support for condition variables. I haven't benchmarked it myself, but there's a good chance your performance will improve when leveraging the native API.

Here's a Code Project article that explains how to access this (relatively new) construct from C#:

A .NET Wrapper for the Vista/Server 2008 Condition Variable


This version atomically unlocks a Mutex or ReaderWriterLockSlim while waiting for signalling, and relocks it before returning - which is the posix way.

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();
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜