AutoResetEvent 的定義
//定義兩個信號鎖
AutoResetEvent ReadTxt = new AutoResetEvent(false);
AutoResetEvent UploadTxt = new AutoResetEvent(false);
默認是false 也就是關閉狀態了。這里要 理解信號 鎖,實際就像某大神說的,把waitone()想象成地鐵的刷卡進站,就是那個刷卡器,你用set()卡刷一次,waitone()由關閉狀態進入打開狀態。運行完waitone下邊剩下的程序。一般waitone不在循環內的話,執行一次,程序結束退出,相當於線程執行的程序退出了,waitone 下次失效,因為程序都失效了,waitone也就沒什么用處了,所以不在循環內,waitone 感覺沒什么鳥用,不重復利用waitone跟set來回切換的話,直接用一個thread 運行一下就好了。
所以要用好上邊的AutoResetEvent 中的waitone和set 中間加循環機制才會實現兩個線程之間,通過set waitone 來回切換。
在學習多線程的過程中,需要循序漸漸,要有耐心,多線程的端倪才會露出,才會慢慢掌握。
就類似下邊一個程序
程序的片段
private void Readtxt(object lst) { AutoResetEvent ReadTxt = (lst as List<AutoResetEvent>)[0]; AutoResetEvent UploadTxt = (lst as List<AutoResetEvent>)[1]; try { string file = Pathstr; ; StreamReader sr = new StreamReader(file, System.Text.Encoding.Default); while (sr.Peek() > -1) { line = sr.ReadLine().ToString().Replace("\r\n", ""); //跳過行空格 if (line.Trim() != "") { Thread.Sleep(50); string[] lines = line.Split("".ToArray(), StringSplitOptions.RemoveEmptyEntries); if (lines.Length >= 3) { zsNum = new NumCon(); zsNum.zsNum = lines[1]; list.Add(zsNum); if (list.Count % 10 == 0) { ReadTxt.WaitOne(); Console.WriteLine("1"); UploadTxt.Set();
ReadTxt.WaitOne(); 是個刷卡器,門禁,程序運行到此停止,需要等待set 命令出現,才會進行下一步,再此就是
ReadTxt.Set(); 它不出現程序就不執行,它出現了,程序執行完下邊的代碼,注意主程序是在循環里邊,執行完下邊的代碼,主程序繼續執行這個循環,又在waitone()
處停下。等待set信號,上邊我這個程序是循環讀取txt內容,每十個加入list中,通過上邊程序,第一次執行到waione() list
中已經加入了10個數,程序運行UploadTxt.Set();時, 主程序也在繼續運行循環里邊的數據,導致讀list的時候,實際是加入了20個數,通過不停的調試,設置斷點,
加代碼,最后才悟到這個問題。
同時設置斷點調試多線程需要注意一下幾個問題
線程的程序若不設置斷點的話,從主程序到線程程序,你按f11是不會逐語句到線程的,可以想想多線是同時並發的,所以在某一刻無法逐語句的。
只有懂得了上邊的概念,不要懷疑程序編譯問題,出錯總有程序邏輯或者自己思維上的誤差導致的。
上邊的方法可以通過概念和 ,你想檢查的地方設置斷點,程序運行過去或者亂跳過去時看看,有時多線程設置斷電點后,和實際運行時結果運行也有差異,在調試上邊
程序時已經充分的體現出來。