Fsharp-events

提供:Dev Guides
移動先:案内検索

F#-イベント

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

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

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

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

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

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

それは、イベントを操作するために次のインスタンスメンバーを持っています-

Member Description
Publish Publishes an observation as a first class value.
Trigger Triggers an observation using the given parameters.

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

Value Description
add : ('T → unit) → Event<'Del,'T> → unit Runs the given function each time the given event is triggered.
choose : ('T → 'U option) → IEvent<'Del,'T> → IEvent<'U> Returns a new event which fires on a selection of messages from the original event. The selection function takes an original message to an optional new message.
filter : ('T → bool) → IEvent<'Del,'T> → IEvent<'T> Returns a new event that listens to the original event and triggers the resulting event only when the argument to the event passes the given function.
map : ('T → 'U) → IEvent<'Del, 'T> → IEvent<'U> Returns a new event that passes values transformed by the given function.
merge : IEvent<'Del1,'T> → IEvent<'Del2,'T> → IEvent<'T> Fires the output event when either of the input events fire.
pairwise : IEvent<'Del,'T> → IEvent<'T *'T> Returns a new event that triggers on the second and subsequent triggering of the input event. The* Nth triggering of the input event passes the arguments from the N-1th and Nth triggering as a pair. The argument passed to the N-1th triggering is held in hidden internal state until the Nth *triggering occurs.
partition : ('T → bool) → IEvent<'Del,'T> → IEvent<'T>* IEvent<'T> Returns a new event that listens to the original event and triggers the first resulting event if the application of the predicate to the event arguments returned true, and the second event if it returned false.
scan : ('U → 'T → 'U) → 'U → IEvent<'Del,'T> → IEvent<'U> Returns a new event consisting of the results of applying the given accumulating function to successive values triggered on the input event. An item of internal state records the current value of the state parameter. The internal state is not locked during the execution of the accumulation function, so care should be taken that the input IEvent not triggered by multiple threads simultaneously.
split : ('T → Choice<'U1,'U2>) → IEvent<'Del,'T> → IEvent<'U1> * IEvent<'U2> Returns a new event that listens to the original event and triggers the first resulting event if the application of the function to the event arguments returned a Choice1Of2, and the second event if it returns a Choice2Of2.

イベントを作成する

イベントは、 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

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

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>型があります-

Method Description
val Add : event:('T → unit) → unit Connects a listener function to the event. The listener will be invoked when the event is fired.
val AddHandler : 'del → unit Connects a handler delegate object to the event. A handler can be later removed using RemoveHandler. The listener will be invoked when the event is fired.
val RemoveHandler : 'del → unit Removes a listener delegate from an event listener store.

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

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

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!