protected override void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { if (ResponseReceived == null) { EneterTrace.Warning(TracedObject + ErrorHandler.NobodySubscribedForMessage); return; } TypedResponseReceivedEventArgs <_ResponseType> aResponseReceivedEventArgs = null; try { _ResponseType aResponseMessage = mySerializer.ForResponseReceiver(AttachedDuplexOutputChannel.ResponseReceiverId).Deserialize <_ResponseType>(e.Message); aResponseReceivedEventArgs = new TypedResponseReceivedEventArgs <_ResponseType>(aResponseMessage); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to deserialize the response message.", err); aResponseReceivedEventArgs = new TypedResponseReceivedEventArgs <_ResponseType>(err); } try { ResponseReceived(this, aResponseReceivedEventArgs); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err); } } }
private void OnResponseReceived(object sender, TypedResponseReceivedEventArgs <MultiTypedMessage> e) { using (EneterTrace.Entering()) { if (e.ReceivingError == null) { TMessageHandler aMessageHandler; using (ThreadLock.Lock(myMessageHandlers)) { myMessageHandlers.TryGetValue(e.ResponseMessage.TypeName, out aMessageHandler); } if (aMessageHandler != null) { object aMessageData; try { aMessageData = mySerializer.ForResponseReceiver(AttachedDuplexOutputChannel.ResponseReceiverId).Deserialize(aMessageHandler.Type, e.ResponseMessage.MessageData); try { aMessageHandler.Invoke(aMessageData, null); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err); } } catch (Exception err) { try { aMessageHandler.Invoke(null, err); } catch (Exception err2) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err2); } } } else { EneterTrace.Warning(TracedObject + ErrorHandler.NobodySubscribedForMessage + " Message type = " + e.ResponseMessage.TypeName); } } else { EneterTrace.Warning(TracedObject + ErrorHandler.FailedToReceiveMessage, e.ReceivingError); } } }
public void RegisterResponseMessageReceiver <T>(EventHandler <TypedResponseReceivedEventArgs <T> > handler) { using (EneterTrace.Entering()) { if (handler == null) { string anError = TracedObject + "failed to register handler for response message " + typeof(T).Name + " because the input parameter handler is null."; EneterTrace.Error(anError); throw new ArgumentNullException(anError); } using (ThreadLock.Lock(myMessageHandlers)) { TMessageHandler aMessageHandler; myMessageHandlers.TryGetValue(typeof(T).Name, out aMessageHandler); if (aMessageHandler != null) { string anError = TracedObject + "failed to register handler for response message " + typeof(T).Name + " because the handler for such class name is already registered."; EneterTrace.Error(anError); throw new InvalidOperationException(anError); } // Note: the invoking method must be cached for particular types because // during deserialization the generic argument is not available and so it would not be possible // to instantiate TypedRequestReceivedEventArgs<T>. Action <object, Exception> anEventInvoker = (message, receivingError) => { TypedResponseReceivedEventArgs <T> anEvent; if (receivingError == null) { anEvent = new TypedResponseReceivedEventArgs <T>((T)message); } else { anEvent = new TypedResponseReceivedEventArgs <T>(receivingError); } handler(this, anEvent); }; myMessageHandlers[typeof(T).Name] = new TMessageHandler(typeof(T), anEventInvoker); } } }
public TResponse SendRequestMessage(TRequest message) { using (EneterTrace.Entering()) { // During sending and receiving only one caller is allowed. using (ThreadLock.Lock(myRequestResponseLock)) { TypedResponseReceivedEventArgs <TResponse> aReceivedResponse = null; EventHandler <TypedResponseReceivedEventArgs <TResponse> > aResponseHandler = (x, y) => { aReceivedResponse = y; myResponseAvailableEvent.Set(); }; mySender.ResponseReceived += aResponseHandler; try { myResponseAvailableEvent.Reset(); try { mySender.SendRequestMessage(message); } catch (Exception err) { string anErrorMessage = TracedObject + ErrorHandler.FailedToSendMessage; EneterTrace.Error(anErrorMessage, err); throw; } // Wait auntil the response is received or the waiting was interrupted or timeout. // Note: use int instead of TimeSpan due to compatibility reasons. if (!myResponseAvailableEvent.WaitOne((int)myResponseReceiveTimeout.TotalMilliseconds)) { string anErrorMessage = TracedObject + "failed to receive the response within the timeout. " + myResponseReceiveTimeout; EneterTrace.Error(anErrorMessage); throw new InvalidOperationException(anErrorMessage); } // If response data does not exist. if (aReceivedResponse == null) { string anErrorMessage = TracedObject + "failed to receive the response."; IDuplexOutputChannel anAttachedOutputChannel = mySender.AttachedDuplexOutputChannel; if (anAttachedOutputChannel == null) { anErrorMessage += " The duplex outputchannel was detached."; } else if (!anAttachedOutputChannel.IsConnected) { anErrorMessage += " The connection was closed."; } EneterTrace.Error(anErrorMessage); throw new InvalidOperationException(anErrorMessage); } // If an error occured during receving the response then throw exception. if (aReceivedResponse.ReceivingError != null) { string anErrorMessage = TracedObject + "failed to receive the response."; EneterTrace.Error(anErrorMessage, aReceivedResponse.ReceivingError); throw new InvalidOperationException(anErrorMessage, aReceivedResponse.ReceivingError); } return(aReceivedResponse.ResponseMessage); } finally { mySender.ResponseReceived -= aResponseHandler; } } } }