引发事件的问题。
引发事件是一个非常容易的事情, 但是的确也有它的误区。 让我们举个例子。 假设我们写个消息接收器, 每当我们收到一个新消息, 我们引发一个包含了新消息的事件messagereceived.
安装我们通常的方法,就是:
public class messagereceivedeventargs : eventargs
// 接收到的消息。
public string message
// 架构 receivedeventargs
public messagereceivedeventargs(string message)
接下来, 我们创建一个非线程安全访问的类unsafemessenger来实现这个消息同时通知所有的订阅者(subscriber).
public class unsafemessenger
public event eventhandler messagereceived;
// 当收到新消息时调用。
public void onnewmessage(string message)
注意, 通常onnewmessage()是私有的, 但是在这里为了测试的方便,我们将它设为public.
大功告成! 是吗? 事实上, 如果我们是单线程的程序, 这的确已经足够, 但是这是非线程安全访问(thread-safe).
为什么? 想想, 订阅者可以任何时候订阅或者取消订阅。 比如,我们当前有一个订阅者, 那么当接收到一个新消息,执行到这一句时:
if (messagereceived !=null)
肯定会通过, 因为有一个订阅者, 如果这个时候, 这名订阅者执行了取消订阅的命令:
-= mymessagehandler;
那么messagereceived委托就为null 了,
/已经通过了这个if语句。
if (messagereceived !=null)
//messagereceived委托就为null 了, 但是我们将要执行这句。
messagereceived(this, new messagereceivedeventargs(message));
这个时候, 就会引发nullreferenceexception.
方案一: 锁住它, 锁机制。
当允许多线程的时候, 我们可以用锁机制来避免一个用户在我们执行事件时订阅或者取消订阅, 或者在用户执行操作时, 不能引发事件。
public class syncronizedmessenger : imessenger
// 委托和锁。
private eventhandler _messagereceived;
private readonly object _raiselock = new object();
// 订阅/取消订阅的锁机制。
public event eventhandler messagereceived
remove }
// 引发事件的锁机制。
public void onnewmessage(string message)
这样, 如果有人试图订阅或取消订阅时, 必须要等待onnewmessage事件的完成, 反之亦然。
方案二: 永不为空, 默认加载一个订阅者。
我们面临的主要问题是有可能委托为空。 那么如果事先加载一个委托,会怎么样?
public class emptysubscribermessenger : imessenger
// 立刻给它一个空的订阅者。
public event eventhandler messagereceived = s, e) =
// 现在根本无需检查是否为 null!
public void onnewmessage(string message)
方案三: 创建一个本地的委托副本。
另外一个简单的方案, 也就是很多人都在使用的, 微软建议的模式: 创建一个本地的委托副本。
public class localcopymessenger : imessenger
public event eventhandler messagereceived;
// 当我们引发事件时, 做一个副本。
public void onnewmessage(string message)
“大黄鸭事件”引发的道德思考作文
道德是一盏明灯,照亮前程的光明 道德是一把火,温暖自己也照亮他人 道德是一剂良药,使你在浮躁的社会中坚守自我。有道德的人,人们对她爱戴,对她尊敬,丧失道德的人人们对她视而不见或唾骂她。总之,有道德的人人恒爱之。为什么大黄鸭漏气就与中国大陆游客有关呢?从中又折射什么样的社会现实呢?不难发现中国大陆游客...
与安全有关的征文
小小的一分钟,在很多人的眼中,脑中根本没有引起重视,其实一分钟也往往决定着一个人一辈子的幸福,你相信吗?小编收集了与安全有关的征文,欢迎阅读。与安全有关的征文一安全这两个字,我们必须时时来记心中。因为在我们身边,每一件事情里都包含了安全。下面我就给大家讲一讲有关安全的一些事例吧!我们国内发生多起校车...
Windows安全事件日志中的事件编号与描述
672 身份验证服务 as 票证得到成功发行与验证。673 票证授权服务 tgs 票证得到授权。tgs是一份由kerberos 5.0版票证授权服务 tgs 发行 且允许用户针对域中特定服务进行身份验证的票证。674 安全主体重建as票证或tgs票证。675 预身份验证失败。这种事件将在用户输入错误...