事件指一個(gè)用戶操作,如按鍵、點(diǎn)擊、移動(dòng)鼠標(biāo)等,也可以是系統(tǒng)生成的通知。當(dāng)事件發(fā)生時(shí),應(yīng)用需要對(duì)其作出相應(yīng)的反應(yīng),如中斷。另外,事件也用于內(nèi)部進(jìn)程通信。
事件生成于類的聲明中,通過(guò)使用同一個(gè)類或其他類中的委托與事件處理程序關(guān)聯(lián)。包含事件的類用于發(fā)布事件,稱為發(fā)布器類。其他接受該事件的類稱為訂閱器類。事件使用的是發(fā)布-訂閱(publisher-subscriber)模型。
發(fā)布器是一個(gè)定義了事件和委托的對(duì)象,此外還定義了事件和委托之間的聯(lián)系。一個(gè)發(fā)布器類的對(duì)象調(diào)用這個(gè)事件,同時(shí)通知其他的對(duì)象。
訂閱器是一個(gè)接受事件并提供事件處理程序的對(duì)象。在發(fā)布器類中的委托調(diào)用訂閱器類中的方法(或事件處理程序)。
在類中聲明一個(gè)事件,首先需要聲明該事件對(duì)應(yīng)的委托類型。如:
public delegate void BoilerLogHandler(string status);
其次為使用 event 關(guān)鍵字來(lái)聲明這個(gè)事件:
//基于上述委托定義事件
public event BoilerLogHandler BoilerEventLog;
上述代碼段定義了一個(gè)名為 BoilerLogHandler 的委托以及一個(gè)名為 BoilerEventLog 的事件,該事件生成時(shí)會(huì)自動(dòng)調(diào)用委托。
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 fired!");
}
}
public EventTest(int n )
{
SetValue(n);
}
public void SetValue(int n)
{
if (value != n)
{
value = n;
OnNumChanged();
}
}
}
public class MainClass
{
public static void Main()
{
EventTest e = new EventTest(5);
e.SetValue(7);
e.SetValue(11);
Console.ReadKey();
}
}
}
編譯執(zhí)行上述代碼,得到如下結(jié)果:
Event Fired!
Event Fired!
Event Fired!
該示例為一個(gè)簡(jiǎn)單的應(yīng)用程序,該程序用于熱水鍋爐系統(tǒng)故障排除。當(dāng)維修工程師檢查鍋爐時(shí),鍋爐的溫度、壓力以及工程師所寫的備注都會(huì)被自動(dòng)記錄到一個(gè)日志文件中。
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;
}
}
// 事件發(fā)布器
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
}
編譯執(zhí)行上述代碼,得到如下結(jié)果:
Logging info:
Temperature 100
Pressure 12
Message: O. K
更多建議: