F # - Acara

Acara memungkinkan kelas untuk mengirim dan menerima pesan antara satu sama lain.

Di GUI, peristiwa adalah tindakan pengguna seperti penekanan tombol, klik, gerakan mouse, dll., Atau beberapa kejadian seperti pemberitahuan yang dihasilkan sistem. Aplikasi perlu merespons peristiwa saat terjadi. Misalnya, menyela. Acara digunakan untuk komunikasi antar proses.

Objek berkomunikasi satu sama lain melalui penyampaian pesan sinkron.

Acara dilampirkan ke fungsi lain; objek mendaftarcallback berfungsi ke suatu peristiwa, dan callback ini dijalankan ketika (dan jika) peristiwa tersebut dipicu oleh beberapa objek.

Kelas Acara dan Modul Acara

Kelas Control.Event <'T> membantu dalam membuat objek atau acara yang dapat diamati.

Ini memiliki anggota contoh berikut untuk bekerja dengan acara -

Anggota Deskripsi
Menerbitkan Menerbitkan observasi sebagai nilai kelas satu.
Pelatuk Memicu pengamatan menggunakan parameter yang diberikan.

Modul Control.Event menyediakan fungsi untuk mengelola aliran acara -

Nilai Deskripsi
tambahkan: ('T → unit) → Peristiwa <' Del, 'T> → unit Menjalankan fungsi tertentu setiap kali peristiwa tertentu dipicu.
pilih: ('T →' U option) → IEvent <'Del,' T> → IEvent <'U> Mengembalikan acara baru yang mengaktifkan pilihan pesan dari acara asli. Fungsi pemilihan membawa pesan asli ke pesan baru opsional.
filter: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> Mengembalikan peristiwa baru yang mendengarkan peristiwa asli dan memicu peristiwa yang dihasilkan hanya ketika argumen ke peristiwa tersebut melewati fungsi yang diberikan.
peta: ('T →' U) → IEvent <'Del,' T> → IEvent <'U> Mengembalikan peristiwa baru yang meneruskan nilai yang diubah oleh fungsi yang diberikan.
gabungkan: IEvent <'Del1,' T> → IEvent <'Del2,' T> → IEvent <'T> Mengaktifkan peristiwa keluaran ketika salah satu peristiwa masukan diaktifkan.
berpasangan: IEvent <'Del,' T> → IEvent <'T *' T> Menampilkan peristiwa baru yang dipicu pada pemicu kedua dan selanjutnya dari peristiwa masukan. ItuNth memicu peristiwa input meneruskan argumen dari N-1th dan Nthmemicu sebagai pasangan. Argumen diteruskan keN-1th memicu diadakan dalam keadaan internal tersembunyi sampai Nth memicu terjadi.
partisi: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> * IEvent <'T> Mengembalikan peristiwa baru yang mendengarkan peristiwa asli dan memicu peristiwa hasil pertama jika penerapan predikat ke argumen peristiwa mengembalikan nilai benar, dan peristiwa kedua jika mengembalikan salah.
scan: ('U →' T → 'U) →' U → IEvent <'Del,' T> → IEvent <'U> Mengembalikan peristiwa baru yang terdiri dari hasil penerapan fungsi akumulasi yang diberikan ke nilai berurutan yang dipicu pada peristiwa masukan. Item status internal mencatat nilai parameter status saat ini. Keadaan internal tidak terkunci selama pelaksanaan fungsi akumulasi, jadi berhati-hatilah agar input IEvent tidak dipicu oleh beberapa utas secara bersamaan.
split: ('T → Choice <' U1, 'U2>) → IEvent <' Del, 'T> → IEvent <' U1> * IEvent <'U2> Mengembalikan kejadian baru yang mendengarkan kejadian asli dan memicu kejadian hasil pertama jika penerapan fungsi ke argumen kejadian mengembalikan Choice1Of2, dan kejadian kedua jika mengembalikan Choice2Of2.

Membuat Acara

Acara dibuat dan digunakan melalui Eventkelas. Konstruktor Acara digunakan untuk membuat acara.

Contoh

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

Setelah ini, Anda perlu mengekspos bidang nameChanged sebagai anggota publik, sehingga pendengar dapat terhubung ke acara yang, Anda menggunakan Publish properti acara -

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 *)

Selanjutnya, Anda menambahkan callback ke event handler. Setiap pengendali kejadian memiliki tipe IEvent <'T>, yang menyediakan beberapa metode -

metode Deskripsi
val Tambahkan: event :( 'T → unit) → unit Menghubungkan fungsi pendengar ke acara tersebut. Pendengar akan dipanggil saat acara dipicu.
val AddHandler: 'del → unit Menghubungkan objek delegasi penangan ke acara tersebut. Sebuah penangan nantinya dapat dihapus menggunakan RemoveHandler. Pendengar akan dipanggil saat acara dipicu.
val RemoveHandler: 'del → unit Menghapus delegasi pendengar dari penyimpanan pendengar acara.

Bagian berikut memberikan contoh lengkapnya.

Contoh

Contoh berikut menunjukkan konsep dan teknik yang dibahas di atas -

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"

Ketika Anda mengkompilasi dan menjalankan program, itu menghasilkan output berikut -

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!