Reputation: 24067
One class Receiver
receives udp datagrams (more than 1000 datagrams every second).
To be OOP I should likely write such code in 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));
.....
Then I can attach any number of Consumers
to this class to be notified about new datagram.
In practice I always have exactly one consumer, so I can just write:
socket.Receive(result);
Consumer.Instance.NewDatagram(result);
And I pretty need to do things fast because it's trading software where each extra millisecond is extra money.
How much slower the first approach is? And how much ugly the second approach?
Upvotes: 1
Views: 816
Reputation: 4165
If there really is only one receiver, I wouldn't create an event. However, I wouldn't directly use the Consumer in the Receiver. Tight coupling should be avoided when there's no reason for it.
While delegates work well (as has already been suggested), you may also want to consider using an interface instead.
Since your consumer directly responds to low-level network events, perhaps at some point you also want it to be informed when other events occur, like e.g. socket closing. When you're using an interface, you just have to create a new method in it and implement it in the consumer and you're done. If you only have a delegate, you would have to create a second one for the new event (and more for any other new events) or have the one delegate handle multiple events, which isn't that great either.
Upvotes: 0
Reputation: 54417
Delegates perform well, so I wouldn't be too concerned with that. I would profile it and see if there is an appreciable difference.
If there truly is a difference, then a tighter coupling of your consumer/receiver is probably your only option (not a terrible option--they are a logical pairing).
As a side note, I have gotten excellent performance by using a small intermediate storage structure (queue, stack, etc.) and dumping incoming data at intervals (rather than message by message). This may or may not be an option for your application.
Upvotes: 0
Reputation: 6728
If there is logically only one receiver you could always take a delegate as a constructor argument and use that as the receiver rather than directly referencing a singleton. That way you have your decoupling with simpler logic.
Upvotes: 3