/// <summary> /// Sends a message and waits a response for that message. /// /// </summary> /// /// <remarks> /// Response message is matched with RepliedMessageId property, so if /// any other message (that is not reply for sent message) is received /// from remote application, it is not considered as a reply and is not /// returned as return value of this method. /// /// MessageReceived event is not raised for response messages. /// /// </remarks> /// <param name="message">message to send</param><param name="timeoutMilliseconds">Timeout duration as milliseconds.</param> /// <returns> /// Response message /// </returns> /// <exception cref="T:System.TimeoutException">Throws TimeoutException if can not receive reply message in timeout value</exception><exception cref="T:Tera.NetworkApi.Communication.Scs.Communication.CommunicationException">Throws CommunicationException if communication fails before reply message.</exception> public IScsMessage SendMessageAndWaitForResponse(IScsMessage message, int timeoutMilliseconds) { RequestReplyMessenger <T> .WaitingMessage waitingMessage = new RequestReplyMessenger <T> .WaitingMessage(); lock (this._syncObj) this._waitingMessages[message.MessageId] = waitingMessage; try { this.Messenger.SendMessage(message); waitingMessage.WaitEvent.Wait(timeoutMilliseconds); switch ((int)waitingMessage.State) { case 0: throw new TimeoutException("Timeout occured. Can not received response."); case 1: throw new CommunicationException("Disconnected before response received."); default: return(waitingMessage.ResponseMessage); } } finally { lock (this._syncObj) { if (this._waitingMessages.ContainsKey(message.MessageId)) { this._waitingMessages.Remove(message.MessageId); } } } }
/// <summary> /// Handles MessageReceived event of Messenger object. /// /// </summary> /// <param name="sender">Source of event</param><param name="e">Event arguments</param> private void Messenger_MessageReceived(object sender, MessageEventArgs e) { if (!string.IsNullOrEmpty(e.Message.RepliedMessageId)) { RequestReplyMessenger <T> .WaitingMessage waitingMessage = (RequestReplyMessenger <T> .WaitingMessage)null; lock (this._syncObj) { if (this._waitingMessages.ContainsKey(e.Message.RepliedMessageId)) { waitingMessage = this._waitingMessages[e.Message.RepliedMessageId]; } } if (waitingMessage != null) { waitingMessage.ResponseMessage = e.Message; waitingMessage.State = (RequestReplyMessenger <T> .WaitingMessageStates) 2; waitingMessage.WaitEvent.Set(); return; } } this._incomingMessageProcessor.EnqueueMessage(e.Message); }
/// <summary> /// Creates a new WaitingMessage object. /// /// </summary> public WaitingMessage() { this.WaitEvent = new ManualResetEventSlim(false); this.State = (RequestReplyMessenger <T> .WaitingMessageStates) 0; }