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