F#事件

2018-12-16 14:21 更新

事件允許類在彼此之間發(fā)送和接收消息。
在GUI中,事件是用戶動(dòng)作,例如按鍵,點(diǎn)擊,鼠標(biāo)移動(dòng)等,或者像系統(tǒng)生成的通知的某些事件。 應(yīng)用程序需要在事件發(fā)生時(shí)對(duì)其進(jìn)行響應(yīng)。 例如,中斷。 事件用于進(jìn)程間通信。
對(duì)象通過(guò)同步消息傳遞彼此通信。
事件附加到其他功能; 對(duì)象將回調(diào)函數(shù)注冊(cè)到事件,并且這些回調(diào)在(和if)事件由某個(gè)對(duì)象觸發(fā)時(shí)執(zhí)行。

事件類和事件模塊

Control.Event <T>類有助于創(chuàng)建可觀察的對(duì)象或事件。
它有以下函數(shù)來(lái)處理事件 

函數(shù)描述
Publish發(fā)布觀察值作為第一類值。
Trigger觸發(fā)器使用給定參數(shù)的觀察。

該Control.Event模塊提供了一個(gè)管理事件流功能 

描述
add : ('T → unit) → Event<'Del,'T> → unit每個(gè)觸發(fā)特定事件時(shí)運(yùn)行給定的功能。
choose : ('T → 'U option) → IEvent<'Del,'T> → IEvent<'U>返回時(shí)觸發(fā)從原始事件選擇消息的新事件。選擇功能需要一個(gè)原始消息到可選的新消息。
filter : ('T → bool) → IEvent<'Del,'T> → IEvent<'T>返回監(jiān)聽(tīng)到原始事件,只有當(dāng)參數(shù)的事件傳遞給定的函數(shù)觸發(fā)所得事件的新事件。
map : ('T → 'U) → IEvent<'Del, 'T> → IEvent<'U>返回傳遞給定函數(shù)轉(zhuǎn)換值的新事件。
merge : IEvent<'Del1,'T> → IEvent<'Del2,'T> → IEvent<'T>觸發(fā)輸出事件時(shí),無(wú)論是輸入事件火。
pairwise : IEvent<'Del,'T> → IEvent<'T * 'T>返回觸發(fā)輸入事件第二次和后續(xù)觸發(fā)的新事件。 輸入事件的第N次觸發(fā)將來(lái)自第N-1和第N次觸發(fā)的自變量作為一對(duì)傳遞。 傳遞到第N-1次觸發(fā)的參數(shù)保持在隱藏內(nèi)部狀態(tài),直到發(fā)生第N次觸發(fā)。
partition : ('T → bool) → IEvent<'Del,'T> → IEvent<'T> * IEvent<'T>返回監(jiān)聽(tīng)到原始事件并觸發(fā)所述第一結(jié)果的事件,如果謂詞事件參數(shù)的應(yīng)用程序返回真一個(gè)新的事件,和第二事件,如果它返回false。
scan : ('U → 'T → 'U) → 'U → IEvent<'Del,'T> → IEvent<'U>返回由施加給定的累積功能來(lái)觸發(fā)輸入事件的連續(xù)值的結(jié)果的一個(gè)新的事件。內(nèi)部狀態(tài)的一個(gè)項(xiàng)目記錄狀態(tài)參數(shù)的當(dāng)前值。內(nèi)部狀態(tài)的累積功能的執(zhí)行期間不被鎖定,所以應(yīng)注意,輸入IEvent不是由多個(gè)線程同時(shí)觸發(fā)。
split : ('T → Choice<'U1,'U2>) → IEvent<'Del,'T> → IEvent<'U1> * IEvent<'U2>返回監(jiān)聽(tīng)到原始事件并觸發(fā)第一所得事件如果該函數(shù)的事件參數(shù)的應(yīng)用程序返回一個(gè)Choice1Of2一個(gè)新的事件,并且如果它返回一個(gè)Choice2Of2第二事件。

創(chuàng)建事件

創(chuàng)建事件,并通過(guò)Event類使用。事件構(gòu)造函數(shù)用于創(chuàng)建一個(gè)事件。

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字段公開(kāi)為公共函數(shù),以便監(jiān)聽(tīng)器可以掛鉤到要使用事件的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 *)

接下來(lái),添加回調(diào)事件處理程序。每個(gè)事件處理程序的類型IEvent <'T>,它提供了幾種方法 

方法描述
VAL地址:事件:('T→單位)→單元連接偵聽(tīng)器函數(shù)事件。當(dāng)事件被觸發(fā)的監(jiān)聽(tīng)器會(huì)被調(diào)用。
VAL的AddHandler:“德?tīng)枴鷨卧?/td>連接處理程序委托對(duì)象的事件。處理程序可使用RemoveHandler在稍后刪除。當(dāng)事件被觸發(fā)的監(jiān)聽(tīng)器會(huì)被調(diào)用。
VAL RemoveHandler:“德?tīng)枴鷨卧?/td>移除事件偵聽(tīng)器店監(jiān)聽(tīng)器委派。

以下部分提供了一個(gè)完整的例子。

下面的示例演示的概念和技術(shù)上面討論 

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"

當(dāng)你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

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!
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)