程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> AutoResetEvent ManualResetEvent WaitOne使用注意事項,autoreseteventreset

AutoResetEvent ManualResetEvent WaitOne使用注意事項,autoreseteventreset

編輯:關於.NET

AutoResetEvent ManualResetEvent WaitOne使用注意事項,autoreseteventreset


公司還用這些老家伙沒辦法,用了幾次這倆。每次用都要重新翻一下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(2000);//設定時間
            Console.WriteLine("end  .." + DateTime.Now.ToString("mm:ss fff"));
            Console.Read();
        }
        //do something
        static void method()
        {
            Thread.Sleep(1000);//阻塞一秒在設置時間內返回
            Console.WriteLine("Async.." + DateTime.Now.ToString("mm:ss fff"));
            a1.Set();
        }

 沒有超過設定時間其他線程通知傳回,本線程不阻塞,跟普通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(2000,false);
            Console.WriteLine("end  .." + DateTime.Now.ToString("mm:ss fff")+ isback);
            Console.Read();
        }
        //do something
        static void method()
        {
            Thread.Sleep(4000); //超時返回
            Console.WriteLine("Async.." + DateTime.Now.ToString("mm:ss fff"));
            a1.Set();
        }

 

 

 

運行結果表示超過兩秒鐘,不阻塞,直接執行,線程另外跑。然後這時間其他線程打開了通知,這個通知狀態一直保存著,下次如果有程序進來,

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(2000, false);
            listBox1.Items.Add("end  .." + DateTime.Now.ToString("mm:ss fff") + isback);
        }
        void method()
        {
            Thread.Sleep(4000); //超時返回
            this.Invoke(new Action(() => { listBox1.Items.Add("Async.." + DateTime.Now.ToString("mm:ss fff")); }));
            a1.Set();
        }
多次點擊就會出現這種,點擊第二次時,第一次其他線程的 set()發揮作用了。不阻塞直接返回了。這種是沒有reset(),這樣就起不到阻塞等待其他方法或線程的作用了




加個reset,清楚下狀態。
            a1.Reset();
            bool isback = a1.WaitOne(2000, true);

以此為標記。如果有錯誤歡迎指正。在此謝過。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved