public TResponse CallSynchronizedHandler <TRequest, TResponse>(TRequest request, int timeout = 10000) { Validate(); Guid correlationId = Guid.NewGuid(); ManualResetEvent mre = new ManualResetEvent(false); SynchronizedDataPackage pkg = new SynchronizedDataPackage(mre); lock (_synchronizationPackages) { while (_synchronizationPackages.ContainsKey(correlationId)) { correlationId = Guid.NewGuid(); } _synchronizationPackages[correlationId] = pkg; } MessageWrapper wrapper = new MessageWrapper { MessageType = MessageType.SynchronizedRequest, Data = request, DataType = typeof(TRequest), ResponseType = typeof(TResponse), CorrelationId = correlationId }; _transport.Publish(wrapper); if (mre.WaitOne(timeout)) { lock (_synchronizationPackages) { TResponse result = (TResponse)_synchronizationPackages[correlationId].Data; _synchronizationPackages.Remove(correlationId); return(result); } } lock (_synchronizationPackages) { _synchronizationPackages.Remove(correlationId); } throw new TimeoutException("Timeout waiting for synchronous call"); }
private void Transport_MessageReceived(object sender, Events.MessageReceivedEventArgs e) { try { MessageWrapper wrapper = e.Message; if (wrapper.MessageType == MessageType.Event) { lock (_eventHandlers) { EventHandler[] handlers = _eventHandlers.Where(h => h.Key.IsAssignableFrom(wrapper.DataType)).SelectMany(h => h.Value).ToArray(); foreach (EventHandler handler in handlers) { try { new Thread(() => { try { if (!handler.Invoke(wrapper.Data)) { _eventHandlers[wrapper.DataType].Remove(handler); } } catch (Exception ex) { PublishUnhandledException(ex); } }).Start(); } catch (Exception ex) { PublishUnhandledException(ex); } } } } else if (wrapper.MessageType == MessageType.SynchronizedRequest) { SynchronizedHandler handler = null; lock (_synchronizedHandlers) { SynchronizedHandlerKey key = new SynchronizedHandlerKey(wrapper.DataType, wrapper.ResponseType); if (_synchronizedHandlers.ContainsKey(key)) { handler = _synchronizedHandlers[key]; if (!handler.IsAlive) { _synchronizedHandlers.Remove(key); } } } if (handler != null && handler.IsAlive) { new Thread(() => { try { object result = handler.Invoke(wrapper.Data); MessageWrapper replyWrapper = new MessageWrapper { MessageType = MessageType.SynchronizedResponse, Data = result, DataType = wrapper.DataType, ResponseType = wrapper.ResponseType, CorrelationId = wrapper.CorrelationId }; _transport.Publish(replyWrapper); } catch (Exception ex) { PublishUnhandledException(ex); } }).Start(); } } else if (wrapper.MessageType == MessageType.SynchronizedResponse) { lock (_synchronizationPackages) { if (_synchronizationPackages.ContainsKey(wrapper.CorrelationId)) { SynchronizedDataPackage pkg = _synchronizationPackages[wrapper.CorrelationId]; pkg.Data = wrapper.Data; pkg.ResetEvent.Set(); } } } } catch (Exception ex) { PublishUnhandledException(ex); } }