Raising events on separate thread

前端 未结 5 1672
耶瑟儿~
耶瑟儿~ 2020-12-29 06:07

I am developing a component which needs to process the live feed and broadcast the data to the listeners in pretty fast manner ( with about 100 nano second level accuracy, e

5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-29 06:46

    It seems like you are looking for tasks. The following is an extension method i wrote for my job that can asynchronously invokes an event so that every event handler is on their own thread. I can't comment on its speed since that has never been a requirement for me.


    UPDATE

    Based on the comments i adjusted it so that only one task is created to call all of the subscribers

    /// 
    /// Extension method to safely encapsulate asynchronous event calls with checks
    /// 
    /// The event to call
    /// The sender of the event
    /// The arguments for the event
    /// The state information that is passed to the callback method
    /// 
    /// This method safely calls the each event handler attached to the event. This method uses  to
    /// asynchronously call invoke without any exception handling. As such, if any of the event handlers throw exceptions the application will
    /// most likely crash when the task is collected. This is an explicit decision since it is really in the hands of the event handler
    /// creators to make sure they handle issues that occur do to their code. There isn't really a way for the event raiser to know
    /// what is going on.
    /// 
    [System.Diagnostics.DebuggerStepThrough]
    public static void AsyncSafeInvoke( this EventHandler evnt, object sender, EventArgs args )
    {
        // Used to make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        EventHandler handler = evnt;
        if (handler != null)
        {
            // Manually calling all event handlers so that we could capture and aggregate all the
            // exceptions that are thrown by any of the event handlers attached to this event.  
            var invocationList = handler.GetInvocationList();
    
            Task.Factory.StartNew(() =>
            {
                foreach (EventHandler h in invocationList)
                {
                    // Explicitly not catching any exceptions. While there are several possibilities for handling these 
                    // exceptions, such as a callback, the correct place to handle the exception is in the event handler.
                    h.Invoke(sender, args);
                }
            });
        }
    }
    

提交回复
热议问题