あけましておめでとうございます。
2023年もよろしくおねがいします!
本日はAutoResetEventについてのメモです。
概要
AutoResetEventは、スレッド処理にて利用すると非常に便利です。
AutoResetEventは、
待機中のスレッドを解放した後、自動的にリセットしてくれます。
イメージは信号機みたいな感じですね。
サンプルコード
例えば、以下のような処理の場合、もちろんスレッド内の出力を待たずに
Console.WriteLine("Done!");
が実行されます。
var t = new Thread(() => { Console.WriteLine("Sleep Start..."); Thread.Sleep(TimeSpan.FromMilliseconds(1000)); Console.WriteLine("Sleep End!"); }); t.Start(); Console.WriteLine("Done!");
実行結果は以下のようになります。
Done! Sleep Start... Sleep End!
では、AutoResetEventを使用してスレッドの処理が完了するのを
待機するようにしてみましょう。
コンストラクタの引数は、シグナルの初期状態を設定します。
trueの場合、初期状態をシグナル状態に設定。
falseの場合、初期状態を非シグナル状態に設定します。
var signal = new AutoResetEvent(false); var t = new Thread(() => { Console.WriteLine("Sleep Start..."); Thread.Sleep(TimeSpan.FromMilliseconds(1000)); Console.WriteLine("Sleep End!"); signal.Set(); }); t.Start(); signal.WaitOne(); Console.WriteLine("Done!");
実行結果は以下のようになります。
Sleep Start... Sleep End! Done!
.Set()
でシグナル状態に設定します。(イメージは信号が青になる感じ)
.WaitOne()
でシグナルを受信するまで待機します。
以下の例の場合、1回目のスリープが終了するまでは待機しますが、
2回目のスリープが開始する前にシグナル状態に設定しているので
2回目のスリープは待機せずConsole.WriteLine("Done!");
が出力されます。
var signal = new AutoResetEvent(false); var t = new Thread(() => { Console.WriteLine("[1]Sleep Start..."); Thread.Sleep(TimeSpan.FromMilliseconds(1000)); Console.WriteLine("[1]Sleep End!"); signal.Set(); Console.WriteLine("[2]Sleep Start..."); Thread.Sleep(TimeSpan.FromMilliseconds(3000)); Console.WriteLine("[2]Sleep End!"); }); t.Start(); signal.WaitOne(); Console.WriteLine("Done!");
実行結果は以下です。
[1]Sleep Start... [1]Sleep End! [2]Sleep Start... Done! [2]Sleep End!
以上です。