WaitOne 方法 (Int32, Boolean):MSDN
msdn的解释中,所谓的"退出同步域"怎么理解?比如:WaitOne(1000, true)与WaitOne(1000, false)
怎么理解呢?
true :等待1秒之后,如果还没有接收到信号,就退出同步域,是不是就不阻塞了,继续执行,还是继续等待1秒?
false:等待1秒之后,如果还没有接收到信号,就不再等待了,此线程终止。
我的理解对吗?
msdn的解释中,所谓的"退出同步域"怎么理解?比如:WaitOne(1000, true)与WaitOne(1000, false)
怎么理解呢?
true :等待1秒之后,如果还没有接收到信号,就退出同步域,是不是就不阻塞了,继续执行,还是继续等待1秒?
false:等待1秒之后,如果还没有接收到信号,就不再等待了,此线程终止。
我的理解对吗?
if (bSucc)
{//做需要同步的事情,
}
else
{
//做其他无需同步的处理,通常是sleep一段时间,然后再次WaitOne
}
我的理解是:如果有快递让我在下班后等他 true的话 我先跑出去溜达了 等他来了我再过来 没消息到时间我就走了
false的话 我一直在办公室等这么长时间 没有消息 哥就不等回家了
WaitHandle是信号系统啊,不是锁系统啊,只要那边一Set,或者说只要接收到信号通知,这边WaitOne就放行
根本与锁无关啊...哎!!个问题困扰好几天了,有没有大师级别的,给予通俗易懂的、详细的解释啊
怎么会继续等待1秒?那不就是等待了2秒,.net类库不会这么白吃的设计 吧
上下文同步域http://technet.microsoft.com/zh-cn/library/kzy257t0(VS.90).aspx
WaitOne 方法详解
不管WaitOne(1000, true)还是WaitOne(1000, false),如果等待1秒之后,还没有接收到信号,就退出阻塞态了,继续执行WaitOne后面的代码,但此时WaitOne返回false;如果在1s内收到信号,则也是继续执行WaitOne后面的代码,此时WaitOne返回true
至于同步域或者同步上下文,貌似跟更加严格的信号量操作有关。
举个例子吧。假设#B和#E之间的代码数据同步域,#B是同步域的开始位置,#E是结束位置
对于WaitOne(1000, true)
#B
WaitOne(1000, true)
A();//某函数A
#E
B();//某函数B
在1秒内没有收到信号,则只会执行函数B。对于WaitOne(1000, false)
#B
WaitOne(1000, false)
A();//某函数A
#E
B();//某函数B
在1秒内没有收到信号,则会执行函数A和B。
[Synchronization(true)]
public class MyTest : ContextBoundObject
{
private EventWaitHandle waitHandle; public MyTest()
{
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
} public void DoWait(object leaveContext)
{
waitHandle.Reset();
Console.WriteLine("这是线程 {0} 的 DoWait 方法。", Thread.CurrentThread.ManagedThreadId);
//阻止当前线程等待消息(true:可以退出同步域,false:不能退出同步域)
bool flag = waitHandle.WaitOne(3000, (Boolean)leaveContext);
if (flag)
{
Console.WriteLine("线程 {0} 等待完成。", Thread.CurrentThread.ManagedThreadId);
}
else
{
Console.WriteLine("线程 {0} 等待超时。", Thread.CurrentThread.ManagedThreadId);
}
} public void Signal()
{
Console.WriteLine("线程 {0} 发个信号!", Thread.CurrentThread.ManagedThreadId);
waitHandle.Set();
}
} public class Program
{
public static void Main()
{
Thread runWaiter;
MyTest mt = new MyTest();
runWaiter = new Thread(mt.DoWait);
runWaiter.Start(false);//不允许退出同步域
Thread.Sleep(1000);
//发送消息
//由于上面的WaitOne不允许退出同步域,所以这里不能进同步域发送消息(只能等待DoWait那个线程退出才能进去),导致等待超时。
mt.Signal();
runWaiter.Join();
Console.WriteLine("这里是主线程 " + Thread.CurrentThread.ManagedThreadId);
//这是线程 4 的 DoWait 方法。
//线程 4 等待超时。
//发个信号!
//这里是主线程 1 Console.WriteLine("\n\n"); runWaiter = new Thread(mt.DoWait);
runWaiter.Start(true);//允许退出同步域
Thread.Sleep(1000);
//发送消息
//这里的WaitOne允许退出同步域,相当于WaitOne的线程暂时退出并等待消息
//主线程进入同步域发消息。WaitOne接受到消息后继续执行。
mt.Signal();
runWaiter.Join();
Console.WriteLine("这里是主线程 " + Thread.CurrentThread.ManagedThreadId);
//这是线程 6 的 DoWait 方法。
//发个信号!
//线程 6 等待完成。
//这里是主线程 1
}
}
写了简单的例子,并加以注释。
同步域中的对象的方法是不能同时被多个线程执行的,也就是说一次只能有一个线程进入同步域。WaitOne 方法 (Int32, Boolean)
int参数:等待多少毫秒
Boolean参数:是否允许当前线程退出同步域,让其他线程进入同步域。为true的时候:他自身线程可以暂时退出同步域,让其他线程进来。等到消息后他才继续执行。
为false的时候:他自己就呆在同步域中等消息。他等待的过程中其他线程也不能进来。
打个比方:
有个厕所只能蹲一个人,你去上厕所,进去后发现没有便意了,你就说我先等3分钟。
那个true or false 就是说你在厕所外面等(true),还是蹲在厕所里面等(false)。
结果等了3分钟还没便意,WaitOne就返回false。如果有了就返回true。
你的便意就是那个信号。
如有不当之处还望见谅,一起探讨!