MicrosoftがGitHubでMITライセンス公開しているWILのGitHub Wikiの記事を和訳・改変したものです。素人による翻訳なので、誤訳や著作権上の問題などありましたらご連絡いただけますと幸いです。
イベントハンドラ(原題:Event handles)
Raymond Chen、2020/8/25、リビジョン2個
unique_event
イベントハンドルラッパーはRAII resource wrappers(原文)の一部としてwil/resource.h
に定義されています。これはイベント処理に特有のメソッドを追加した特殊化unique_any(原文)です。呼び出し側コードの要求するエラー処理スタイルに基づいて3つの版があります。
wil::unique_event e1; // 失敗は例外をスローする。 wil::unique_event_nothrow e2; // 失敗は`HRESULT`を返す。 wil::unique_event_failfast e3; // 失敗はプロセスを強制終了する。 // コンストラクタの中で作成される(unique_event_nothrowの使用は許可されない)。 wil::unique_event e4(wil::EventOptions::ManualReset); // 標準操作 e1.ResetEvent(); e1.SetEvent(); // スコープから出るときの標準操作 auto setOnExit = e1.SetEvent_scope_exit(); auto resetOnExit = e1.ResetEvent_scope_exit(); // 手動リセットイベントがシグナルされているかチェックする。 if (e1.is_signaled()) {} // ある(オプション)時間だけ待機する。 if (e1.wait(5000)) {} // イベントを作成または開く。 e1.create(wil::EventOptions::ManualReset); e1.open(L"MyEventName"); if (e1.try_create(wil::EventOptions::ManualReset, L"MyEventName")) {} if (e1.try_open(L"MyEventName")) {}
unique_event
クラスは意図的にHANDLE
と同じサイズであり、その配列はキャストにより複数オブジェクトを要求する処理関数で使えることに注意してください。
unique_event
の外部でイベントハンドルを扱う場合、WILは同様のパターンをまねたいくつかの簡単な関数を定義しています。
// スコープから出る場合の標準操作 auto setOnExit = SetEvent_scope_exit(handle); auto resetOnExit = ResetEvent_scope_exit(handle); // 手動リセットイベントがシグナルされているかチェックする。 if (event_is_signaled(handle)) {} // ある(オプション)時間だけ待機する。 if (handle_wait(5000)) {}
unique_event
には軽量版のwil::slim_event
があります。詳細は以下を参照してください(訳註:記述中?)。
イベントの監視
WILはさらにunique_event_watcher
を定義しています。これはイベントシグナルのサブスクライブとシグナル時の提供された関数の実行を簡単にします。また、イベントハンドルの作成、既存イベントハンドルの所有権取得、提供されたハンドルの複製を可能とします。複数のシグナルがひとつのコールバックに合体することには注意してください。
wil::unique_event_watcher watcher; // 失敗は例外をスローする。 wil::unique_event_watcher_nothrow watcher; // 失敗はHRESULT(またはnullptr)を返す。 wil::unique_event_watcher_failfast watcher; // 失敗はプロセスを強制終了する。 // 与えられたイベントハンドルを複製して、イベントのシグナル時に与えられたラムダ式を実行する。 watcher.create(event, [] { // code ... }); // 与えられたunique_eventの所有権を取得して、イベントのシグナル時に与えられたラムダ式を実行する。 watcher.create(std::move(event), [] { // code ... }); // イベントハンドルを作成して(get_eventで取得可能)、イベントのシグナル時に与えられたラムダ式を実行する。 watcher.create([] { // code ... }); // イベントハンドルの保持に内部で使用されるunique_event_nothrowを取得する。 // (前掲のunique_eventのフルコントラクトを公開する) auto handle& = watcher.get_event(); // イベントの監視を開始する。 void SetEvent() const WI_NOEXCEPT { get()->m_event.SetEvent(); }
make_event_watcher
ルーチンとその多様なフレーバー(複数のオーバーロード、make_event_watcher_nothrow
やmake_event_watcher_failfast
を含む)はローカルで使用するイベントウォッチャーの作成を簡単にします。
auto watcher = wil::make_event_watcher(handle, [] { // code ... });
ウォッチャーオブジェクト(およびunique_event_watcher
自体)はunique_any class(原文)の特殊化インスタンスであり、サブスクリプションの解除にreset
のような操作を使えることに注意してください。
See also
著作権表示
この記事は以下の著作物を使用しています。
Copyright (c) Microsoft Corporation. All rights reserved. https://github.com/microsoft/wil/blob/master/LICENSE