Oleg Vazhnev
Oleg Vazhnev

Reputation: 24067

Events VS just method call?

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

Answers (3)

enzi
enzi

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

Tim M.
Tim M.

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

SimonC
SimonC

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

Related Questions