/// <summary> Unsubscribes the given <paramref name="messageConsumer"/> from the dispatcher. </summary> /// <param name="messageConsumer">Message consumer</param> public void Unsubscribe(IMessageConsumer messageConsumer) { if (messageConsumer == null) { return; } ConsumerEntry[] registeredConsumer = _registeredConsumers.Access(_ => _.ToArray()); ConsumerEntry entry = registeredConsumer.FirstOrDefault(_ => _.MessageConsumer == messageConsumer); if (entry == null) { return; } _registeredConsumers.Access(_ => _.Remove(entry)); }
/// <summary> /// Is invoked when the message dispatcher thread has been started. /// </summary> /// <param name="o">Reference to the message dispatcher</param> private void ReadAndDispatch(object o) { MessageDispatcher messageDispatcher = (MessageDispatcher)o; while (_isAlive.Get()) { // Wait until a signal is received messageDispatcher._processQueueEvent.Wait(); // Reset messageDispatcher._processQueueEvent.Reset(); // Collect consumer and events EnqueuedEvent[] queuedEvents = messageDispatcher._eventQueue.Access(list => { var buffer = list.ToArray(); list.Clear(); return(buffer); }); ConsumerEntry[] registeredConsumers = messageDispatcher._registeredConsumers.Access(_ => _.ToArray()); // Get the set UI thread dispatcher or set a fake one UIThreadDispatcher uiThreadDispatcher = UIThreadDispatcher ?? (_ => _()); // Dispatch for (int i = -1; ++i != queuedEvents.Length;) { EnqueuedEvent queuedEvent = queuedEvents[i]; for (int j = -1; ++j != registeredConsumers.Length;) { ConsumerEntry consumerEntry = registeredConsumers[j]; // Anonymous function to dispatch the event void dispatchEvent() { try { consumerEntry.MessageConsumer.OnMessageReceived(queuedEvent.Sender, queuedEvent.EventArguments, consumerEntry.DataObject); } catch (Exception ex) { string errorMessage = $"Error on dispatching event to '{consumerEntry.MessageConsumer.GetType()}'. Reason: {ex}"; Error?.Invoke(errorMessage); } } // Dispatch event using the configured thread try { if (consumerEntry.UIThreadDispatch) { uiThreadDispatcher(dispatchEvent); } else { dispatchEvent(); } } catch (Exception ex) { string errorMessage = $"Error on invoking event dispatch to '{consumerEntry.MessageConsumer.GetType()}'. Reason: {ex}"; Error?.Invoke(errorMessage); } } } } }