看了这么久,对于C#的事件机制还是一头雾水。
最让我迷惑不解的是事件的处理方法是在什么时候执行的。
看到的文档都是说是在事件发生的时候被调用。结合看到的例程,
如果是定时的事件,我还可以理解,但是如果没有那么明显的事件的标志,
对于事件对于我就变成一只黑匣子了。
后来看了一篇教程,我感觉我对事件的理解错了。原来事件并不一定是
外来的例如计时或者中断,在C#中事件只是一种模型,使方法之间可以互相交互和
影响,建立一定的关联,从而实现特定的功能。事实上,事件在生成的时候调用委托的。
事件生成是一个很广泛的概念,既可以是时间,按键,也可以是方法的调用。(也许前者就是
方法的调用)。
下面是引用自http://www.runoob.com/csharp/csharp-event.html的例程
下面的代码就是一个以方法调用作为事件的例子。
其中的事件就是OnBoilerEventLog()方法的调用
所以我的拙见是任何触发包装在event中的方法的对象都是事件
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
}
对于一个问题的认识总是由浅入深的,今天看到了一篇文章,对事件又有了更深的理解。贴一下这篇文章
“事件驱动机制”里的事件和c#中的event不是一回事。就像java和c++里没有event这个关键字并且不用delegate。但是它们在处理GUI程序时却都是用事件驱动机制来完成。
从机制上讲,事件就是你干了什么,你点击了一个button,选择了一个下拉菜单,点击关闭按钮。那么这个时候程序该怎么反应呢?这就看你的事件(或者说动作)有谁关心和谁关联。
拿button为例,它有一个事件叫单击,当单击发生时,button会发布一个消息“我被单击了”;在这之前关心这个问题的类会跟这个事件注册一下,就是说我订阅你的消息,当你事件发生时,这个消息要给我知道。而当订阅者知道事情发生了它就会采取相应的处理也就是调用自己预先写好的事件处理方法。
拿现实为例,出版社会发行报纸,而一个事件发生(比方某煤矿瓦斯爆炸)它会出现在报纸上,这就是一个消息;而如果你想知道发生了什么,你就要订阅报纸,这样每有消息,都会把报纸送到你家的邮箱;不同的人收到报纸他就会有不同的反应做出不同的处理,比方家人在那个煤矿的人和投资了那个煤矿的人就会做不同反应。
在实现上,c#是用委托做的,事件是一个特殊的委托,不用事件也能完成,但是可能会出现问题,就是有人可以绕过你这个事件发生而使用委托即事件没发生却可以从后台调用你的事件处理方法,为了限制这个行为采用关键字event来修饰委托或者说创建了一个“事件”的概念。
而在java中,是用Listener来做的,你一个事件源负责发布消息,而关心它的类会有一个Listener并在内部编写事件处理方法,而在事件源中addActionListener就是把外部的一个关心者注册起来,表示别人关心你订阅了你的消息。
链接:https://zhidao.baidu.com/question/50339292.html