0

Based on the accepted answer in How do I make an eventhandler run asynchronously?:

class TestHarness
{

static void Main(string[] args)
{
    var raiser = new SomeClass();

    // Emulate some event listeners
    raiser.SomeEvent += (sender, e) => { Console.WriteLine("   Received event"); };
    raiser.SomeEvent += (sender, e) =>
    {
        // Bad listener!
        Console.WriteLine("   Blocking event");
        System.Threading.Thread.Sleep(5000);
        Console.WriteLine("   Finished blocking event");
    };

    // Listener who throws an exception
    raiser.SomeEvent += (sender, e) =>
    {
        Console.WriteLine("   Received event, time to die!");
        throw new Exception();
    };

    // Raise the event, see the effects
    raiser.DoSomething();

    Console.ReadLine();
}
}

class SomeClass
{
public event EventHandler SomeEvent;

public void DoSomething()
{
    OnSomeEvent();
}

private void OnSomeEvent()
{
    if (SomeEvent != null)
    {
        var eventListeners = SomeEvent.GetInvocationList();

        Console.WriteLine("Raising Event");
        for (int index = 0; index < eventListeners.Count(); index++)
        {
            var methodToInvoke = (EventHandler)eventListeners[index];
            methodToInvoke.BeginInvoke(this, EventArgs.Empty, EndAsyncEvent, null);
        }
        Console.WriteLine("Done Raising Event");
    }
}

private void EndAsyncEvent(IAsyncResult iar)
{
    var ar = (System.Runtime.Remoting.Messaging.AsyncResult)iar;
    var invokedMethod = (EventHandler)ar.AsyncDelegate;

    try
    {
        invokedMethod.EndInvoke(iar);
    }
    catch
    {
        // Handle any exceptions that were thrown by the invoked method
        Console.WriteLine("An event listener went kaboom!");
    }
}
}

How do I ensure, that the BeginInvoke of each delegate is called one after another? I mean, I want to treat every registered handler of the event in a different thread, but each call to BeginInvoke of a delegate should be on the same thread, so that they do not overlap.

To my understanding BeginInvoke is called on a new thread even it is the same delegate it is called on, hence the delegate could be called in parallel causing ordering issues in the eventhandler.

All things put together: How do I call all delegates asynchronously, but each of the delegates in sequential order?

Background is: Some eventhandlers may need the eventargs in "real time", some do processing. The real time eventhandlers should not be slowed down by other handlers and the order of the eventargs must be in correct sequential order as they occured.

Creepin
  • 482
  • 4
  • 20
  • You need to block between event handlers that need to run in order. So one process doesn't run until previous finishes. See following : https://msdn.microsoft.com/en-us/library/58195swd(v=vs.110).aspx – jdweng Sep 23 '17 at 10:00
  • May you elaborate this in more detail? Where should I put the waithandle? Within the event handlers or on publisher side? I cannot imagine how to introduce this in the given code – Creepin Sep 23 '17 at 10:45
  • Would need to see more code. What ever makes sense. You may want to look at the socket example at msdn : https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.100).aspx – jdweng Sep 23 '17 at 16:22

0 Answers0