我的类有一个外部对象将订阅的事件:
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
但是,在其自己的线程上运行的内部Listener对象实际上将发起该事件。
private class Listener
{
public void Run()
{
// events raised here which should be forwarded
// to parent's MessageReceived
}
};
我倾向于在Listener上创建一个具有相同签名的事件,并在主类中订阅它以便在MessageReceived上引发它。这看起来有点麻烦,所以我想知道是否有一种简洁/惯用的方式来转发这样的事件。
答案 0 :(得分:22)
您可以使用事件add/remove accessors,以便将连接到面向外部事件的事件“转发”到内部侦听器
public event EventHandler<MessageReceivedEventArgs> MessageReceived {
add { this.listener.MessageRecieved += value; }
remove { this.listener.MessageRecieved -= value; }
}
这意味着你需要在监听器中创建一个事件,但好处是没有其他的管道来连接事件。
答案 1 :(得分:1)
您可以使用事件执行此操作,或者您可以在主类中创建一个名为ReceiveMessage()的方法,并从侦听器调用该方法(然后从那里引发事件)。
答案 2 :(得分:1)
如上所述,您可以使用添加和删除处理程序的自定义订阅逻辑。
请注意,此设计存在问题。您指定您的侦听器在其自己的线程中引发事件。默认情况下,将在引发事件的线程上调用处理程序(在您的情况下,是监听器的线程)。你有几个选择。
Roy Osherove的博客文章显示了几种执行异步调用的方法:http://weblogs.asp.net/rosherove/pages/DefensiveEventPublishing.aspx (但我不会在委托上使用异步调用,而是直接依赖ThreadPool来调用委托)。