事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。
C# 中使用事件机制实现线程间的通信。
通过事件使用委托
事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。
发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。
订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。
声明事件(Event)
在类的内部声明事件,首先必须声明该事件的委托类型。例如:
public delegate void BoilerLogHandler(string status);
然后,声明事件本身,使用 event 关键字:
// 基于上面的委托定义事件 public event BoilerLogHandler BoilerEventLog;
上面的代码定义了一个名为 BoilerLogHandler 的委托和一个名为 BoilerEventLog 的事件,该事件在生成的时候会调用委托。
实例
实例 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 + " \n Pressure: " + p ) ;
OnBoilerEventLog ( " \n Message: " + 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