AutoResetEvent ManualResetEvent WaitOne使用注意事项

公司还用这些老家伙没办法,用了几次这俩。每次用都要重新翻一下A片。

好好的A片楞是翻译成了禅经。把这东西弄成个玄学。微软也是吃枣药丸。参考了@风中灵药的blog.写的牛逼。

还有一些公司用到的风中灵药没有提及,我给自己留个tip.好以后看看。有错误希望大家指出。虽然我不一定改。

AutoResetEvent 、ManualResetEvent 两个用法都差不多。

无非是ManualResetEvent 可以通知到多个线程,然后开启后默认不关闭。需要手动关闭。

AutoResetEvent a1 = new AutoResetEvent(false);

ManualResetEvent m1 = new ManualResetEvent(false);

如果初始为true,就跟没有这两个东西一样,起不到阻塞当前线程,等待通知的继续运行的效果。所以用的时候都是初始化成false.

所以初始化为true有毛用。那当初为啥这样设计。翻了下金刚经更不懂了。等有缘人解答、

WaitOne();

这个如果初始化的AutoResetEvent 为false.如果没有set(),他会一直阻塞,也就是说就成死锁了。

--vs2012  win10 .net4.6.1

WaitOne(int); WaitOne(int,bool); WaitOne(timespan,bool);

这三个一样。int单位为毫秒,timespan就是时间间隔。

(1)这个如果初始化的AutoResetEvent 为false.如果在设置时间内返回,跟普通的wait()效果一样,阻塞然后运行;

static AutoResetEvent a1 = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(method));
th.Start();
Console.WriteLine("start.."+DateTime.Now.ToString("mm:ss fff"));
bool isback = a1.WaitOne();//设定时间
Console.WriteLine("end .." + DateTime.Now.ToString("mm:ss fff"));
Console.Read();
}
//do something
static void method()
{
Thread.Sleep();//阻塞一秒在设置时间内返回
Console.WriteLine("Async.." + DateTime.Now.ToString("mm:ss fff"));
a1.Set();
} AutoResetEvent ManualResetEvent WaitOne使用注意事项

没有超过设定时间其他线程通知传回,本线程不阻塞,跟普通waitone一样。

(2)如果在设置时间内没有set(),时间在超过设置时间后就不会阻塞了。直接返回。貌似神器,可以设置时间然后运行一个线程或者异步的方法,然后超过一定时间返回给前面说超时了。

开发中用的这种情况很多啊。但是,如果异步方法或者线程在设置超时时间后set();那么下次再来到这个是可以直接运行的。不会引起阻塞。你需要reset()一下

返回参数为true代表 set触发,

返回参数为false代表超过设定时间,自动触发。

static AutoResetEvent a1 = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(method));
th.Start();
Console.WriteLine("start.."+DateTime.Now.ToString("mm:ss fff"));
bool isback = a1.WaitOne(,false);
Console.WriteLine("end .." + DateTime.Now.ToString("mm:ss fff")+ isback);
Console.Read();
}
//do something
static void method()
{
Thread.Sleep(); //超时返回
Console.WriteLine("Async.." + DateTime.Now.ToString("mm:ss fff"));
a1.Set();
}

AutoResetEvent ManualResetEvent WaitOne使用注意事项

运行结果表示超过两秒钟,不阻塞,直接执行,线程另外跑。然后这时间其他线程打开了通知,这个通知状态一直保存着,下次如果有程序进来,

bool isback = a1.WaitOne(2000,false);这里就不会阻塞,直接通过。
AutoResetEvent a1 = new AutoResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(method));
th.Start();
listBox1.Items.Add("start.." + DateTime.Now.ToString("mm:ss fff"));
bool isback = a1.WaitOne(, false);
listBox1.Items.Add("end .." + DateTime.Now.ToString("mm:ss fff") + isback);
}
void method()
{
Thread.Sleep(); //超时返回
this.Invoke(new Action(() => { listBox1.Items.Add("Async.." + DateTime.Now.ToString("mm:ss fff")); }));
a1.Set();
}
多次点击就会出现这种,点击第二次时,第一次其他线程的 set()发挥作用了。不阻塞直接返回了。这种是没有reset(),这样就起不到阻塞等待其他方法或线程的作用了
AutoResetEvent ManualResetEvent WaitOne使用注意事项 加个reset,清楚下状态。
            a1.Reset();
bool isback = a1.WaitOne(, true);

AutoResetEvent ManualResetEvent WaitOne使用注意事项

以此为标记。如果有错误欢迎指正。在此谢过。
上一篇:【总结】牛客职播第九期:您的美团点评offer已送到门口,快来与我们一起影响世界!


下一篇:如何rename sqlserver database