F # - กิจกรรม
เหตุการณ์ช่วยให้ชั้นเรียนสามารถส่งและรับข้อความระหว่างกันได้
ใน GUI เหตุการณ์คือการกระทำของผู้ใช้เช่นการกดแป้นการคลิกการเคลื่อนไหวของเมาส์ ฯลฯ หรือบางเหตุการณ์เช่นการแจ้งเตือนที่ระบบสร้างขึ้น แอปพลิเคชันจำเป็นต้องตอบสนองต่อเหตุการณ์เมื่อเกิดขึ้น ตัวอย่างเช่นขัดจังหวะ เหตุการณ์ใช้สำหรับการสื่อสารระหว่างกระบวนการ
ออบเจ็กต์สื่อสารกันผ่านข้อความซิงโครนัส
กิจกรรมจะแนบไปกับฟังก์ชันอื่น ๆ ลงทะเบียนวัตถุcallback ฟังก์ชันกับเหตุการณ์และการเรียกกลับเหล่านี้จะดำเนินการเมื่อ (และถ้า) เหตุการณ์ถูกทริกเกอร์โดยวัตถุบางอย่าง
คลาสเหตุการณ์และโมดูลเหตุการณ์
คลาส Control.Event <'T> ช่วยในการสร้างวัตถุหรือเหตุการณ์ที่สังเกตได้
มีสมาชิกอินสแตนซ์ต่อไปนี้เพื่อทำงานกับเหตุการณ์ -
สมาชิก | คำอธิบาย |
---|---|
เผยแพร่ | เผยแพร่การสังเกตเป็นค่าชั้นหนึ่ง |
ทริกเกอร์ | ทริกเกอร์การสังเกตโดยใช้พารามิเตอร์ที่กำหนด |
โมดูล Control.Event จัดเตรียมฟังก์ชันสำหรับจัดการสตรีมเหตุการณ์ -
มูลค่า | คำอธิบาย |
---|---|
เพิ่ม: ('T →หน่วย) →เหตุการณ์ <' Del, '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> | ส่งคืนเหตุการณ์ใหม่ที่ทริกเกอร์ในเหตุการณ์อินพุตที่สองและตามมา Nth การทริกเกอร์ของเหตุการณ์อินพุตจะส่งผ่านอาร์กิวเมนต์จากไฟล์ N-1th และ Nthทริกเกอร์เป็นคู่ อาร์กิวเมนต์ส่งผ่านไปยังN-1th การทริกเกอร์จะถูกเก็บไว้ในสถานะภายในที่ซ่อนอยู่จนถึง Nth การกระตุ้นเกิดขึ้น |
พาร์ติชัน: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> * IEvent <'T> | ส่งคืนเหตุการณ์ใหม่ที่รับฟังเหตุการณ์เดิมและทริกเกอร์เหตุการณ์ที่เป็นผลลัพธ์แรกหากการประยุกต์ใช้เพรดิเคตกับอาร์กิวเมนต์เหตุการณ์ส่งคืนเป็นจริงและเหตุการณ์ที่สองหากส่งคืนเป็นเท็จ |
สแกน: ('U →' T → 'U) →' U → IEvent <'Del,' T> → IEvent <'U> | ส่งคืนเหตุการณ์ใหม่ที่ประกอบด้วยผลลัพธ์ของการใช้ฟังก์ชันการสะสมที่กำหนดกับค่าต่อเนื่องที่ทริกเกอร์ในเหตุการณ์อินพุต รายการของสถานะภายในบันทึกค่าปัจจุบันของพารามิเตอร์สถานะ สถานะภายในไม่ได้ถูกล็อกระหว่างการทำงานของฟังก์ชันการสะสมดังนั้นควรใช้ความระมัดระวังว่า IEvent อินพุตจะไม่ถูกทริกเกอร์โดยเธรดหลายเธรดพร้อมกัน |
แยก: ('T →ทางเลือก <' U1, 'U2>) → IEvent <' Del, 'T> → IEvent <' U1> * IEvent <'U2> | ส่งคืนเหตุการณ์ใหม่ที่รับฟังเหตุการณ์ดั้งเดิมและทริกเกอร์เหตุการณ์ที่เป็นผลลัพธ์แรกหากการประยุกต์ใช้ฟังก์ชันกับอาร์กิวเมนต์เหตุการณ์ส่งคืน Choice1Of2 และเหตุการณ์ที่สองหากส่งคืน 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
หลังจากนี้คุณจะต้องเปิดเผยฟิลด์ 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 เพิ่ม: เหตุการณ์ :( 'T →หน่วย) →หน่วย | เชื่อมต่อฟังก์ชันผู้ฟังกับเหตุการณ์ ผู้ฟังจะถูกเรียกเมื่อเหตุการณ์เริ่มทำงาน |
val AddHandler: 'del →หน่วย | เชื่อมต่ออ็อบเจ็กต์ผู้รับมอบสิทธิ์ตัวจัดการกับเหตุการณ์ ตัวจัดการสามารถลบออกได้ในภายหลังโดยใช้ 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!