Raising events on separate thread

前端 未结 5 1589
耶瑟儿~
耶瑟儿~ 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条回答
  •  囚心锁ツ
    2020-12-29 06:41

    I can't speak to if this will reliably meet the 100ns requirement but here's an alternative where you'd provide the end user with a way to provide you a ConcurrentQueue that you would fill and they could listen to on a separate thread.

    class Program
    {
        static void Main(string[] args)
        {
            var multicaster = new QueueMulticaster();
    
            var listener1 = new Listener(); //Make a couple of listening Q objects. 
            listener1.Listen();
            multicaster.Subscribe(listener1);
    
            var listener2 = new Listener();
            listener2.Listen();
            multicaster.Subscribe(listener2);
    
            multicaster.Broadcast(6); //Send a 6 to both concurrent Queues. 
            Console.ReadLine();
        }
    }
    
    //The listeners would run on their own thread and poll the Q like crazy. 
    class Listener : IListenToStuff
    {
        public ConcurrentQueue StuffQueue { get; set; }
    
        public void Listen()
        {
            StuffQueue = new ConcurrentQueue();
            var t = new Thread(ListenAggressively);
            t.Start();
    
        }
    
        void ListenAggressively()
        {
            while (true)
            {
                int val;
                if(StuffQueue.TryDequeue(out val))
                    Console.WriteLine(val);
            }
        }
    }
    
    //Simple class that allows you to subscribe a Queue to a broadcast event. 
    public class QueueMulticaster
    {
        readonly List> _subscribers = new List>();
        public void Subscribe(IListenToStuff subscriber)
        {
            _subscribers.Add(subscriber);
        }
        public void Broadcast(T value)
        {
            foreach (var listenToStuff in _subscribers)
            {
                listenToStuff.StuffQueue.Enqueue(value);
            }
        }
    }
    
    public interface IListenToStuff
    {
        ConcurrentQueue StuffQueue { get; set; }
    }
    

    Since given the fact that you can't hold up processing on other listeners this means multiple threads. Having dedicated listening threads on the listeners seems like a reasonable approach to try, and the concurrent queue seems like a decent delivery mechanism. In this implementation it's just constantly polling, but you could probably use thread signaling to reduce the cpu load using something like AutoResetEvent.

提交回复
热议问题