11

I want to raise a series of events from my library class, but I'm worried that some event subscribers will be rude and take a long time to process some events, thus blocking the thread that is raising the events. I thought I could protect the raising thread by using a thread pool thread to raise each event:

if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    DataPacketReceived.BeginInvoke(this, args, null, null);
}

That works fine when there's only one subscriber to the event, but as soon as a second subscriber arrives, DataPacketReceived becomes a multicast delegate, and I get an argument exception with the error message, "The delegate must have only one target." Is there an easy way to raise the event on a separate thread, or do I have to start a thread and then raise the event from there?

Dmitrii Lobanov
  • 4,897
  • 1
  • 33
  • 50
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286

1 Answers1

16

I found a similar question on another site, and of course Jon Skeet had answered it. For my scenario, I chose to raise the event for each subscriber on a separate thread:

if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    var receivers = DataPacketReceived.GetInvocationList();
    foreach (EventHandler<DataPacketEventArgs> receiver in receivers)
    {
        receiver.BeginInvoke(this, args, null, null);
    }
}
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
  • 2
    Correct, but note that calling `BeginInvoke` on each individual subscriber does not necessarily mean that each will run on a separate thread. It's the thread-pool's business. – Ani Dec 23 '11 at 05:46
  • 2
    I've been looking at this issue a few times over the last few days, It's important to note that the objects in `receivers` aren't actually of type `EventHandler`, that's an explicit cast. – Trent Scheffert Dec 02 '14 at 20:26