WaitHandle.WaitOne()中的exitContext参数作用

WaitOne()、WaitAny()、WaitAll()方法中都有一个带有Boolean类型变量的重载方法。msdn对这个变量的介绍是:

true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it afterward; otherwise, false.

简单的说就是在调用WaitOne方法的时候,是否先退出所在同步域,等方法返回之后再重新获取同步域。
同步域可以理解成只允许单线程执行,不允许并发的一块代码区域。一个线程先进入了同步域,其他线程如果想进入,只能等待这个线程退出同步域。如果WaitOne()执行的时候指定exitContext参数是true,那么WaitOne()等待信号的时候,其他线程可以进入改同步域。
后面的注释有更详细的介绍:

The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. This can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

只有在“非默认上下文”中该参数才有效。什么是“非默认上下文”呢,后面的介绍是一个继承了ContextBoundObject的类的实例调用的线程,那么这个线程就在“非默认上下文”中。继承ContextBoundObject类的同时还要使用SynchronizationAttribute属性修饰。

class Program
    {
        static void Main(string[] args)
        {
            BaseClass firstClass = new BaseClass();
            ChildClass secondClass = firstClass.GetChildClass(); 
            Thread firstThread = new Thread(firstClass.method);
            Thread secondThread = new Thread(secondClass.method);
            firstThread.Start();
            Thread.Sleep(500);//先让firstThread执行起来
            secondThread.Start();
            Console.Read();
        }
    }

    [Synchronization(true)]
    class BaseClass : ContextBoundObject//BaseClass继承了ContextBoundObject,并且Synchronization修饰,是一个同步域
    {
        public static ManualResetEvent mre = new ManualResetEvent(false);
        public static Stopwatch stopwatch = new Stopwatch();
        public virtual void method()
        {
            stopwatch.Start();
            Console.WriteLine("BaseClass method begin");
            mre.WaitOne(3000,true);//如果为true,先退出同步域,此时ChildClass可以执行了;如果为false,先不退出,只有BaseClass执行完,ChildClass才能执行
            Console.WriteLine("BaseClass method end after {0} ms",stopwatch.ElapsedMilliseconds);
            stopwatch.Stop();
        }

        public ChildClass GetChildClass()
        {
            return new ChildClass();
        }
    }
    class ChildClass : BaseClass//继承了BaseClass,ChildClass和BaseClass属于同一个同步域
    {
        public override void method()
        {
            Console.WriteLine("ChildClass method entered synchromization domain after {0} ms", stopwatch.ElapsedMilliseconds);
        }
    }

其中mre.WaitOne 方法参数为true,输出如下:

BaseClass method begin
ChildClass method entered synchromization domain after 524 ms
BaseClass method end after 3001 ms

mre.WaitOne 方法参数为false,输出如下:

BaseClass method begin
BaseClass method end after 3008 ms
ChildClass method entered synchromization domain after 3008 ms

你可能感兴趣的:(C#,WaitOne,exitContex)