How do I make an eventhandler run asynchronously?

前端 未结 7 654
迷失自我
迷失自我 2020-12-04 11:15

I am writing a Visual C# program that executes a continuous loop of operations on a secondary thread. Occasionally when that thread finishes a task I want it to trigger an e

相关标签:
7条回答
  • 2020-12-04 12:09

    So you want to raise the event in a manner that prevents the listeners from blocking the background thread? Gimme a couple minutes to whip up an example; it's pretty simple :-)

    Here we go: first an important note! Whenever you call BeginInvoke you must call the corresponding EndInvoke, otherwise if the invoked method threw an exception or returned a value then the ThreadPool thread will never be released back to the pool, resulting in a thread-leak!

    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!");
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题