C# 事件 Event
c# 事件 event
事件(event) 基本上說是一個用戶操作,如按鍵、點擊、鼠標移動等等,或者是一些提示信息,如系統生成的通知。應用程序需要在事件發生時響應事件。例如,中斷。
c# 中使用事件機制實現線程間的通信。
1. 通過事件使用委托
事件在類中聲明且生成,且通過使用同一個類或其他類中的委托與事件處理程序關聯。包含事件的類用于發布事件。這被稱為 發布器(publisher) 類。其他接受該事件的類被稱為 訂閱器(subscriber) 類。事件使用 發布-訂閱(publisher-subscriber) 模型。
發布器(publisher) 是一個包含事件和委托定義的對象。事件和委托之間的聯系也定義在這個對象中。發布器(publisher)類的對象調用這個事件,并通知其他的對象。
訂閱器(subscriber) 是一個接受事件并提供事件處理程序的對象。在發布器(publisher)類中的委托調用訂閱器(subscriber)類中的方法(事件處理程序)。
2. 聲明事件(event)
在類的內部聲明事件,首先必須聲明該事件的委托類型。例如:
public delegate void boilerloghandler(string status);
然后,聲明事件本身,使用 event 關鍵字:
// 基于上面的委托定義事件 public event boilerloghandler boilereventlog;
上面的代碼定義了一個名為 boilerloghandler 的委托和一個名為 boilereventlog 的事件,該事件在生成的時候會調用委托。
3. 范例
范例 1:
using system; namespace simpleevent { ? using system; ? /***********發布器類***********/ ? public class eventtest ? { ? ? private int value; ? ? public delegate void nummanipulationhandler(); ? ? public event nummanipulationhandler changenum; ? ? protected virtual void onnumchanged() ? ? { ? ? ? if ( changenum != null ) ? ? ? { ? ? ? ? changenum(); /* 事件被觸發 */ ? ? ? }else { ? ? ? ? console.writeline( "event not fire" ); ? ? ? ? console.readkey(); /* 回車繼續 */ ? ? ? } ? ? } ? ? public eventtest() ? ? { ? ? ? int n = 5; ? ? ? setvalue( n ); ? ? } ? ? public void setvalue( int n ) ? ? { ? ? ? if ( value != n ) ? ? ? { ? ? ? ? value = n; ? ? ? ? onnumchanged(); ? ? ? } ? ? } ? } ? /***********訂閱器類***********/ ? public class subscribevent ? { ? ? public void printf() ? ? { ? ? ? console.writeline( "event fire" ); ? ? ? console.readkey(); /* 回車繼續 */ ? ? } ? } ? /***********觸發***********/ ? public class mainclass ? { ? ? public static void main() ? ? { ? ? ? eventtest e = new eventtest(); /* 范例化對象,第一次沒有觸發事件 */ ? ? ? subscribevent v = new subscribevent(); /* 范例化對象 */ ? ? ? e.changenum += new eventtest.nummanipulationhandler( v.printf ); /* 注冊 */ ? ? ? e.setvalue( 7 ); ? ? ? e.setvalue( 11 ); ? ? } ? } }
當上面的代碼被編譯和執行時,它會產生下列結果:
event not fire event fire event fire
本范例提供一個簡單的用于熱水鍋爐系統故障排除的應用程序。當維修工程師檢查鍋爐時,鍋爐的溫度和壓力會隨著維修工程師的備注自動記錄到日志文件中。
范例 2:
using system; using system.io; namespace boilereventappl { ? ?// boiler 類 ? ?class boiler ? ?{ ? ? ? private int temp; ? ? ? private int pressure; ? ? ? public boiler(int t, int p) ? ? ? { ? ? ? ? ?temp = t; ? ? ? ? ?pressure = p; ? ? ? } ? ? ? public int gettemp() ? ? ? { ? ? ? ? ?return temp; ? ? ? } ? ? ? public int getpressure() ? ? ? { ? ? ? ? ?return pressure; ? ? ? } ? ?} ? ?// 事件發布器 ? ?class delegateboilerevent ? ?{ ? ? ? public delegate void boilerloghandler(string status); ? ? ? // 基于上面的委托定義事件 ? ? ? public event boilerloghandler boilereventlog; ? ? ? public void logprocess() ? ? ? { ? ? ? ? ?string remarks = "o. k"; ? ? ? ? ?boiler b = new boiler(100, 12); ? ? ? ? ?int t = b.gettemp(); ? ? ? ? ?int p = b.getpressure(); ? ? ? ? ?if(t > 150 || t < 80 || p < 12 || p > 15) ? ? ? ? ?{ ? ? ? ? ? ? remarks = "need maintenance"; ? ? ? ? ?} ? ? ? ? ?onboilereventlog("logging info:\n"); ? ? ? ? ?onboilereventlog("temparature " + t + "\npressure: " + p); ? ? ? ? ?onboilereventlog("\nmessage: " + remarks); ? ? ? } ? ? ? protected void onboilereventlog(string message) ? ? ? { ? ? ? ? ?if (boilereventlog != null) ? ? ? ? ?{ ? ? ? ? ? ? boilereventlog(message); ? ? ? ? ?} ? ? ? } ? ?} ? ?// 該類保留寫入日志文件的條款 ? ?class boilerinfologger ? ?{ ? ? ? filestream fs; ? ? ? streamwriter sw; ? ? ? public boilerinfologger(string filename) ? ? ? { ? ? ? ? ?fs = new filestream(filename, filemode.append, fileaccess.write); ? ? ? ? ?sw = new streamwriter(fs); ? ? ? } ? ? ? public void logger(string info) ? ? ? { ? ? ? ? ?sw.writeline(info); ? ? ? } ? ? ? public void close() ? ? ? { ? ? ? ? ?sw.close(); ? ? ? ? ?fs.close(); ? ? ? } ? ?} ? ?// 事件訂閱器 ? ?public class recordboilerinfo ? ?{ ? ? ? static void logger(string info) ? ? ? { ? ? ? ? ?console.writeline(info); ? ? ? }//end of logger ? ? ? static void main(string[] args) ? ? ? { ? ? ? ? ?boilerinfologger filelog = new boilerinfologger("e:\\boiler.txt"); ? ? ? ? ?delegateboilerevent boilerevent = new delegateboilerevent(); ? ? ? ? ?boilerevent.boilereventlog += new ? ? ? ? ?delegateboilerevent.boilerloghandler(logger); ? ? ? ? ?boilerevent.boilereventlog += new ? ? ? ? ?delegateboilerevent.boilerloghandler(filelog.logger); ? ? ? ? ?boilerevent.logprocess(); ? ? ? ? ?console.readline(); ? ? ? ? ?filelog.close(); ? ? ? }//end of main ? ?}//end of recordboilerinfo }
當上面的代碼被編譯和執行時,它會產生下列結果:
logging info: temperature 100 pressure 12 message: o. k