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

来源:互联网 发布:貂蝉网络剑三蘑菇助手 编辑:程序博客网 时间:2024/05/14 08:59

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

0 0
原创粉丝点击