📜  F#-事件

📅  最后修改于: 2020-11-21 07:02:00             🧑  作者: Mango


事件允许类之间相互发送和接收消息。

在GUI中,事件是用户操作,例如按键,单击,鼠标移动等,或某些事件(例如系统生成的通知)。应用程序需要在事件发生时做出响应。例如,中断。事件用于进程间通信。

对象通过同步消息传递相互通信。

事件附加到其他功能;对象将回调函数注册到事件,并且(如果有)事件由某个对象触发时执行这些回调。

事件类和事件模块

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类创建和使用的。 Event构造函数用于创建事件。

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

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

之后,您需要将nameChanged字段公开为公共成员,以便侦听器可以挂接到事件上,您可以使用事件的Publish属性-

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

   let nameChanged = new Event() (* creates event *)
   let shiftChanged = new Event() (* 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 

接下来,将回调添加到事件处理程序。每个事件处理程序的类型为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() (* creates event *)
   let shiftChanged = new Event() (* 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  printfn "Worker changed name! New name: %s" wk.Name)
wk.Name  printfn "-- Another handler attached to NameChanged!")
wk.Name  printfn "Worker changed shift! New shift: %s" wk.Shift)
wk.Shift  printfn "-- Another handler attached to ShiftChanged!")
wk.Shift 

编译并执行程序时,将产生以下输出-

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!