Can I use BeginInvoke with a MulticastDelegate?
Asked Answered
T

1

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?

Takakotakakura answered 19/1, 2011 at 1:59 Comment(0)
T
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);
    }
}
Takakotakakura answered 19/1, 2011 at 1:59 Comment(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.Baras
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<DataPacketEventArgs>, that's an explicit cast.Talaria

© 2022 - 2024 — McMap. All rights reserved.