异步调用Eventhandler但按顺序调用

时间:2017-09-23 09:06:26

标签: c# multithreading asynchronous event-handling

根据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!");
    }
}
}

如何确保每个委托的BeginInvoke一个接一个地调用?我的意思是,我想在不同的线程中处理事件的每个已注册的处理程序,但是每个对委托的BeginInvoke的调用应该在同一个线程上,这样它们就不会重叠。

据我所知,在一个新线程上调用BeginInvoke,即使它是被调用的同一个委托,因此可以并行调用委托,从而导致在事件处理程序中出现排序问题。

所有内容放在一起:如何异步调用所有代理,但每个代理按顺序调用?

背景是:某些事件处理程序可能需要“实时”的事件标记,有些会进行处理。实时事件处理程序不应该被其他处理程序减慢,并且事件标记的顺序必须按照它们发生时的正确顺序排列。

0 个答案:

没有答案