なんだかGoodVibes

日々の勉強メモです。

【C#】AutoResetEventメモ

あけましておめでとうございます。
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!



以上です。