1

システムがスリープ状態になったときに閉じる必要があるデバイス ドライバーを使用しています。次のように、 SystemEvents.PowerModeChangedイベントのハンドラーを ApplicationEvents.vb に追加できると考えました。

Public Sub SystemEvents_PowerModeChanged(sender As Object, e As PowerModeChangedEventArgs) _
        Handles SystemEvents.PowerModeChanged

    If e.Mode = PowerModes.Suspend Then
        logger.Trace("The computer is suspending. Closing device.")
        'Close device
    ElseIf e.Mode = PowerModes.Resume Then
        logger.Trace("The computer is resuming operation from suspend mode. Opening device.")
        ' Open device
    End If
End Sub

Handlesキーワードを使用してイベントを処理します。ただし、Handles 句にはコンパイル エラーがあります。

Handles clause requires a WithEvents variable defined in the containing type or one of its base types.

WithEvents は、.NET で遭遇する他のイベントに対して常に定義されているようですが、なぜこれが異なるのでしょうか? ハンドラーの追加と削除が自動化されるため、Handles 句を使用することをお勧めします。また、機能をイニシャライザ、デストラクタ、および関数自体に分散させるのではなく、自己完結型に保ちます。このイベントでハンドル宣言を使用することは可能ですか?

この問題の手がかりは、次のコードが機能することです。

AddHandler SystemEvents.PowerModeChanged, AddressOf SystemEvents_PowerModeChanged
4

1 に答える 1

3

SystemEvents クラスのイベントは、慣れ親しんだ種類のものとは異なり、静的イベントです。vb.netの「共有」は話します。これは、 「システム」が1 つしか存在しないことを理解することで理解できます。したがって、イベントのソースは 1 つだけです。

WithEvents に関する MSDN 記事のこのテキストは、次のようになります。

クラス インスタンスを受け入れることができるように、WithEvents 変数をオブジェクト変数として宣言する必要があります。

SystemEvents タイプのオブジェクト変数は作成できません。したがって、WithEvents キーワードは使用できません。したがって、Handles 句も使用できません。にフォールバックすることAddHandlerは、非常に難しい要件です。

そして、非常に重要なことRemoveHandlerですが、イベントに関心がなくなったときに明示的に使用する必要があります。フォームの FormClosed イベント ハンドラーなど。UI がなくなったときに SystemEvents がイベント ハンドラーのトリガーを停止するために必要です。これを忘れると、メモリ リークが発生し (フォーム オブジェクトをガベージ コレクションできません)、運が良ければ ObjectDisposedException が発生します。フォームまたはウィンドウを閉じるとアプリも終了する場合にのみ、この要件をスキップできます。

于 2014-08-25T15:32:48.180 に答える