【发布时间】:2010-05-13 19:30:31
【问题描述】:
我有一个静态泛型类,它可以帮助我以很少的开销移动事件:
public static class MessageBus<T> where T : EventArgs
{
public static event EventHandler<T> MessageReceived;
public static void SendMessage(object sender, T message)
{
if (MessageReceived != null)
MessageReceived(sender, message);
}
}
要创建系统范围的消息总线,我只需要定义一个 EventArgs 类来传递任意位的信息:
class MyEventArgs : EventArgs
{
public string Message { get; set; }
}
只要我对这个事件感兴趣,我就连接一个处理程序:
MessageBus<MyEventArgs>.MessageReceived += (s,e) => DoSomething();
同样,触发事件同样简单:
MessageBus<MyEventArgs>.SendMessage(this, new MyEventArgs() {Message="hi mom"});
使用 MessageBus 和自定义 EventArgs 类可以让我为特定类型的消息提供应用程序范围的消息接收器。当您有多个表单(例如,显示客户信息)以及可能更新该信息的几个表单时,这会派上用场。所有表单都不知道彼此,也不需要连接到静态“超类”。
我有几个问题:
fxCop 抱怨使用带有泛型的静态方法,但这正是我在这里所追求的。我希望处理的每种消息类型都只有一个 MessageBus。使用带有泛型的静态使我免于编写维护 MessageBus 对象列表的所有代码。
监听对象是否通过 MessageReceived 事件保持“活动”?
例如,也许我在 Form.Load 事件中有这段代码:
MessageBus<CustomerChangedEventArgs>.MessageReceived += (s,e) => DoReload();
当窗体关闭时,窗体是否保留在内存中,因为 MessageReceived 引用了它的 DoReload 方法?我是否应该在表单关闭时删除引用:
MessageBus<CustomerChangedEventArgs>.MessageReceived -= (s,e) => DoReload();
【问题讨论】:
-
很多关于#2 的有用反馈...谢谢!有人在#1 上有 cmets 吗?为什么认为使用这种方法“不好”?