事件VS只是方法调用

本文关键字:方法 调用 VS 事件 | 更新日期: 2023-09-27 18:27:19

一个类Receiver接收udp数据报(每秒超过1000个数据报)。

为了OOP,我可能会在Receiver 中编写这样的代码

public event EventHandler<NewDatagramEventArgs> NewMessage;
protected virtual void OnNewMessage(NewDatagramEventArgs e)
{
    if (NewDatagram != null)
        NewDatagram(this, e);
}
....
socket.Receive(result)
....
OnNewMessage(new NewDatagramEventArgs(result));
.....

然后,我可以将任意数量的Consumers附加到这个类,以获得关于新数据报的通知。

在实践中,我总是只有一个消费者,所以我可以写:

socket.Receive(result);
Consumer.Instance.NewDatagram(result);

我非常需要快速做事,因为这是一种交易软件,每多出一毫秒就是额外的钱。

第一种方法要慢多少?第二种方法有多难看?

事件VS只是方法调用

如果逻辑上只有一个接收器,您可以始终将委托作为构造函数参数,并将其用作接收器,而不是直接引用单例。这样你就可以用更简单的逻辑实现解耦。

委托执行得很好,所以我不会太担心这一点。我会对它进行分析,看看是否有明显的差异。

如果确实存在差异,那么消费者/接收者之间的紧密耦合可能是你唯一的选择(这不是一个糟糕的选择——它们是一个逻辑配对)。

顺便说一句,我使用了一个小型的中间存储结构(队列、堆栈等),并每隔一段时间(而不是逐个消息)转储传入数据,从而获得了出色的性能。这可能是您的应用程序的一个选项,也可能不是。

如果真的只有一个接收器,我就不会创建事件。但是,我不会直接在Receiver中使用Consumer。在没有理由的情况下,应避免紧密耦合。

虽然代理工作良好(正如已经建议的那样),但您可能还需要考虑使用接口。

由于您的消费者直接响应低级别的网络事件,也许在某个时候,您还希望在发生其他事件时通知它,例如套接字关闭。当你使用一个接口时,你只需要在其中创建一个新方法,并在使用者中实现它,你就完成了。如果只有一个代理,则必须为新事件创建第二个代理(为任何其他新事件创建更多代理),或者让一个代理处理多个事件,这也不太好。