風のエリクシルのブログからの抜粋:https://www.cnblogs.com/qingyun163/archive/2013/01/05/2846633.html#!comments
AutoResetEvenトンとManualResetEventは:三つの重要な方法で、スレッドの一時停止を制御したり、継続して使用することができWAITONE、設定およびリセット。
各スレッドは、車に比較した場合、その後、AutoResetEventとManualResetEventは、道路上の料金所です。
どこで:
リセット ブレーキが通行止めに閉じられた料金所は、(我々は車両料ああを傍受するために行きます)。
WAITONE 低料金来る車両の待機(および料金)。
セット 料金所のブレーキ解除(過去をできるように支払う)を開きます。
AutoResetEventとManualResetEventの違い
以来AutoResetEventとManualResetEventすべての料金所、そしてそれらの間の違いは何であるのか?
名前が示唆するように、自動自動的に、手動すなわち手動、リセット前者は自動的にブレーキを手動でシャットダウンする必要が閉ブレーキ、すなわち、上記近い類似ブレーキを示します。
自動的にブレーキをオフにする:車がによって支払う後、ブレーキが自動的にシャットダウンします、その後、賃金の上に次の車を待ちます。つまり、各車両は非常に多くの段階を経る必要があり、次のとおりです。閉じて抵抗>貢献>の通路>ブレーキ
閉じるブレーキが手動で手動で(すなわち呼び出しブレーキオフになっていない場合は、リアブレーキを開き、ブレーキが自動的に閉じないManualResetEvent.Reset()メソッド)を、次いで、車両はによってバンパーになり......
AutoResetEvent初期状態とManualResetEvent
提供することによりAutoResetEventとManualResetEventコンストラクタを有料ブレーキ状態を初期化します。
オート新しい新/ ManualResetEvent(偽):デフォルトでは、ブレーキオフ、
新しい新しいオート/ ManualResetEvent(真の): デフォルトで有効になってブレーキ。
場合は、新しい新しいオート/ ManualResetEvent(trueに)、それはデフォルトでオンになって、そしてブレーキは、デフォルトで最初の車を聞かせて、次の車をブロックします。
静的 EventWaitHandle _tollStation = 新しい新しい(AutoResetEvent 真の); // ブレーキがデフォルトで有効になって 静的 ボイドメイン(文字列[]引数)を { 新しい新しいスレッド(CAR1).Start(); Console.ReadKey(); } 静的 ボイドCAR1() { _tollStation .WaitOne(); // デフォルトでオンにブレーキので、WAITONEの無意味は、車両のフロントライン防ぐことはできません Console.WriteLineをを(「!ブレーキが開いている悲しいかな、私が来ます!」); }
この出力には:「ああブレーキが開放されて、私が来る!!」
しかし場合は、それを変更します
静的 EventWaitHandle _tollStation = 新新(AutoResetEvent 真の); // ブレーキはデフォルトで有効になっている 静的な 無効メイン(文字列[] argsは) { 新しい新しいスレッド(CAR1).Start(); 新しい新しいスレッド(CAR1).Start(); // 2を実行二次出力スレッド Console.ReadKeyを(); } 静的 無効CAR1() { _tollStation.WaitOne(); // デフォルトでオンにブレーキので、WAITONEの無意味、車両のフロントライン防ぐことはできません Console.WriteLineを(" 車ああを!ゲートが開いている、私が来ます!" ); }
この出力時:ああ!ブレーキが開いている、私が来ます!
一度だけ二つのスレッドが、出力を実行します。第二は、ブロックされましたので。
場合は(真の)新しいAutoResetEvent 代わりに新しい新しいAutoResetEvent(flase)は、すなわち、ブレーキがデフォルトでオフになって、それは車両が通過することができない任意の値を表示しません。
どのようにそれを渡すことができますか?これは、メインスレッドで呼び出される必要がありますセットブレーキで開くことができる方法。
静的 EventWaitHandle _tollStation = 新新(AutoResetEvent falseに); // ブレーキはデフォルトではオフになっている 静的な 無効メイン(文字列[] argsを) { 新しい新しいスレッド(CAR1).Start(); _tollStation.Set(); // オープンブレーキ Console.ReadKey (); } 静的 無効CAR1() { _tollStation.WaitOne(); // ;なっブレーキ、すなわち_event.Set()待って Console.WriteLineをする(" 私は来にブレーキ!" ); }
プリントラン:
ブレーキ上、私が来ます!
コードは非常に明確で、短いでは、説明されていない場合、デフォルトでブレーキオフになっている、唯一の(呼び出しブレーキを開く設定方法を)、車両が通過することができます。
特性を有する符号の説明AutoResetEvent
静的 EventWaitHandle _tollStation = 新しい新しい AutoResetEvent(偽の); // ブレーキがデフォルトでオフになって 静的 ボイドメイン(文字列[]引数) { 新しい新しいスレッド(CAR1).Start(); // 車両1つの 新しい新しいスレッド(CAR2).Start(); // 車両2 _tollStation.Set(); Console.ReadKey(); } 静的 ボイドCAR1() { _tollStation.WaitOne(); // 開いてブレーキを待つ、すなわち_tollStation.Set(); Console.WriteLineを(" 車両1、合格しました。」); } 静的 ボイドCAR2() { _tollStation.WaitOne(); Console.WriteLineを(" !車両2渡さ" ); }
プリントラン:
車両1、渡されました。
車両1と2車両が実行されているが、唯一の1車両が通過している間。
以来_tollStation.Set()は一度だけ実行され、すなわち、ブレーキを介して車両1の直後に車両2が経過していない原因、オフにされます。
車両1で再び、ない限り呼び出すことによって_tollStation.Setを()に2によって再びブレーキ、車両を開きます。
静的 EventWaitHandle _tollStation = 新しい新しい AutoResetEvent(偽の); // ブレーキがデフォルトでオフになって 静的 ボイドメイン(文字列[]引数) { 新しい新しいスレッド(CAR1).Start(); // 車両1つの 新しい新しいスレッド(CAR2).Start(); // 車両2 _tollStation.Set(); // によって車両1となるよう、ブレーキを開き 、Console.ReadKey() } 静的 ボイドCAR1() { _tollStation.WaitOne(); //は、オープン即ち_tollStationにブレーキを待ちます。 SET(); Console.WriteLineを("車両1、渡されました。" ); _TollStation.Set(); //は次いでスルーように車両2、ブレーキを開く } 静的 ボイドCAR2() { _tollStation.WaitOne(); Console.WriteLineを(" 車両2が通過しました。" ); }
プリントラン:
車両1、渡されました。
2台の車両は、渡されました。
各呼び出しはセット、1つのスレッドのみ継続されます。言い換えれば、どのように多くのスレッドは何回呼び出す必要がありますセットのすべてのスレッドが続行されます。
また、示しAutoResetEventキュー操作の典型的な形を。
特性を有する符号の説明ManualResetEvent
コードブロックでは、_tollStation.Set()は二回、2台の車が通過したと呼ばれています。
だから、どのような方法は、一度だけ呼び出すことがあり_tollStation.Set()が 2台の以上の車がそれを通過してみましょうか?
答えはということですAutoResetEventが変更さManualResetEventを:
静的 EventWaitHandle _tollStation = 新しい新しい(ManualResetEvent はfalse); // ManualResetEvent、デフォルトでブレーキオフの 静的 ボイドメイン(文字列[]引数) { 新しい新しいスレッド(CAR1).Start(); // 車両1つの 新しい新しいスレッド(CAR2)。スタート(); // 車両2 _tollStation.Setは(); // ブレーキを開き、車両が全て通過する 。Console.ReadKey() } 静的 ボイドCAR1() { ; _tollStation.WaitOne()//は、ブレーキ開放待ちます即ち_tollStation.Set(); Console.WriteLineを(" 車両1は、渡された。" ); // _tollStation.Set(); // これは必要でなくなった } 静的 ボイドCAR2() { _tollStation.WaitOne(); Console.WriteLineを("、車両2合格します" ); }
プリントラン:
車両1、渡されました。
2台の車両は、渡されました。
これは、非常に良い説明ですManualResetEventが自動的にブレーキを投入した後、この機能をオフにしません。だから、一度呼び出さ_tollStation.Set() 、すべての車両が通過します。
あなたはいくつかの点で、手動でブレーキをオフにした場合、車両の後部には渡しません。次のコードのように:
静的 EventWaitHandle _tollStation = 新しい新しい(ManualResetEvent はfalse); // ManualResetEvent、デフォルトでブレーキオフの 静的 ボイドメイン(文字列[]引数) { 新しい新しいスレッド(CAR1).Start(); // 車両1つの 新しい新しいスレッド(CAR2)。 [スタート](); // 車両2 _tollStation.Set(); // オープンブレーキ、リリース =タイマタイマ新しい新しいタイマー(CloseDoor、ヌル、0、2000); // 2秒後に閉じるブレーキ Console.ReadKey(); } 静的 ボイドCAR1() { _tollStation.WaitOne(); // 待機ブレーキ開放、即ち_tollStation.Set(); Console.WriteLineを(" 車両1は、渡された。" ); } 静的 ボイドCAR2() { のThread.sleep (3000); // 睡眠3秒 _tollStation.WaitOne(); // ブレーキがウェイクオフされた場合 Console.WriteLineを(「通過車両2。」); // 車両2によるものでないように } /// <要約> /// オフ2秒ブレーキ後 /// </要約> 静的 ボイド CloseDoor(オブジェクトO) { _tollStation.Reset(); // 閉じるブレーキ }
プリントラン:
車両1、渡されました。
ブレーキが2秒をオフにする前に、2と車両が時に車両2ウェイクアップするので、渡しません。