F#-イベント

イベントを使用すると、クラスは相互にメッセージを送受信できます。

GUIでは、イベントは、キーの押下、クリック、マウスの動きなどのユーザーアクション、またはシステム生成の通知などの発生です。アプリケーションは、イベントが発生したときにイベントに応答する必要があります。たとえば、割り込み。イベントは、プロセス間通信に使用されます。

オブジェクトは、同期メッセージパッシングを通じて相互に通信します。

イベントは他の関数に関連付けられています。オブジェクト登録callback イベントへの関数であり、これらのコールバックは、イベントが何らかのオブジェクトによってトリガーされたとき(およびその場合)に実行されます。

イベントクラスとイベントモジュール

Control.Event <'T>クラスは、監視可能なオブジェクトまたはイベントの作成に役立ちます。

イベントを操作するための次のインスタンスメンバーがあります-

メンバー 説明
公開する 観測値をファーストクラスの値として公開します。
引き金 指定されたパラメーターを使用して観測をトリガーします。

Control.Eventモジュールは、イベントストリームを管理するための関数を提供します-

説明
追加:( 'T→ユニット)→イベント<'デル、 'T>→ユニット 指定されたイベントがトリガーされるたびに、指定された関数を実行します。
選択:( 'T→' Uオプション)→IEvent <'Del、' T>→IEvent <'U> 元のイベントから選択したメッセージで発生する新しいイベントを返します。選択機能は、元のメッセージをオプションの新しいメッセージに変換します。
フィルタ:( 'T→bool)→IEvent <' Del、 'T>→IEvent <' T> 元のイベントをリッスンし、イベントへの引数が指定された関数を渡した場合にのみ結果のイベントをトリガーする新しいイベントを返します。
マップ:( 'T→' U)→IEvent <'Del、' T>→IEvent <'U> 指定された関数によって変換された値を渡す新しいイベントを返します。
マージ:IEvent <'Del1、' T>→IEvent <'Del2、' T>→IEvent <'T> いずれかの入力イベントが発生すると、出力イベントが発生します。
ペアワイズ:IEvent <'Del、' T>→IEvent <'T *' T> 入力イベントの2回目以降のトリガーでトリガーされる新しいイベントを返します。ザ・Nth 入力イベントのトリガーは、からの引数を渡します N-1th そして Nthペアとしてトリガーします。に渡された引数N-1th トリガーは、 Nth トリガーが発生します。
パーティション:( 'T→bool)→IEvent <' Del、 'T>→IEvent <' T> * IEvent <'T> 元のイベントをリッスンし、イベント引数への述語の適用がtrueを返した場合は最初の結果のイベントをトリガーし、falseを返した場合は2番目のイベントをトリガーする新しいイベントを返します。
スキャン:( 'U→' T→ 'U)→' U→IEvent <'Del、' T>→IEvent <'U> 指定された累積関数を入力イベントでトリガーされた連続する値に適用した結果で構成される新しいイベントを返します。内部状態の項目は、状態パラメーターの現在の値を記録します。累積関数の実行中は内部状態がロックされないため、入力IEventが複数のスレッドによって同時にトリガーされないように注意する必要があります。
分割:( 'T→Choice <' U1、 'U2>)→IEvent <' Del、 'T>→IEvent <' U1> * IEvent <'U2> 元のイベントをリッスンし、イベント引数への関数の適用がChoice1Of2を返した場合は最初の結果のイベントをトリガーし、Choice2Of2を返した場合は2番目のイベントをトリガーする新しいイベントを返します。

イベントの作成

イベントは、を通じて作成および使用されます Eventクラス。イベントコンストラクターは、イベントの作成に使用されます。

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;
   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.Name
      with get() = _name
      and set(value) = _name <- value

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value

この後、nameChangedフィールドをパブリックメンバーとして公開する必要があります。これにより、リスナーはイベントにフックできます。 Publish イベントのプロパティ-

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.NameChanged = nameChanged.Publish (* exposed event handler *)
   member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *)

   member this.Name
      with get() = _name
      and set(value) = _name <- value
      nameChanged.Trigger() (* invokes event handler *)

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value
   shiftChanged.Trigger() (* invokes event handler *)

次に、イベントハンドラーにコールバックを追加します。各イベントハンドラーのタイプはIEvent <'T>で、いくつかのメソッドを提供します-

方法 説明
val Add:event :( 'T→unit)→unit リスナー関数をイベントに接続します。イベントが発生すると、リスナーが呼び出されます。
val AddHandler: 'del→unit ハンドラーデリゲートオブジェクトをイベントに接続します。ハンドラーは、後でRemoveHandlerを使用して削除できます。イベントが発生すると、リスナーが呼び出されます。
val RemoveHandler: 'del→unit イベントリスナーストアからリスナーデリゲートを削除します。

次のセクションでは、完全な例を示します。

次の例は、上記の概念と手法を示しています。

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.NameChanged = nameChanged.Publish (* exposed event handler *)
   member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *)

   member this.Name
      with get() = _name
      and set(value) = 
         _name <- value
         nameChanged.Trigger() (* invokes event handler *)

   member this.Shift
      with get() = _shift
      and set(value) = 
         _shift <- value
         shiftChanged.Trigger() (* invokes event handler *)

let wk = new Worker("Wilson", "Evening")
wk.NameChanged.Add(fun () -> printfn "Worker changed name! New name: %s" wk.Name)
wk.Name <- "William"
wk.NameChanged.Add(fun () -> printfn "-- Another handler attached to NameChanged!")
wk.Name <- "Bill"

wk.ShiftChanged.Add(fun () -> printfn "Worker changed shift! New shift: %s" wk.Shift)
wk.Shift <- "Morning"
wk.ShiftChanged.Add(fun () -> printfn "-- Another handler attached to ShiftChanged!")
wk.Shift <- "Night"

プログラムをコンパイルして実行すると、次の出力が生成されます。

Worker changed name! New name: William
Worker changed name! New name: Bill
-- Another handler attached to NameChanged!
Worker changed shift! New shift: Morning
Worker changed shift! New shift: Night
-- Another handler attached to ShiftChanged!