private void SocketAsyncEventArgs_SendComplete(object sender, SocketAsyncEventArgs e) { #if Matrix_Diagnostics InstanceMonitor monitor = Monitor; if (monitor != null && monitor.IsReportAllowed) { monitor.Info(string.Format("Send complete, sender [{0}].", sender != null ? sender.ToString() : string.Empty)); } #endif e.Completed -= new EventHandler <SocketAsyncEventArgs>(SocketAsyncEventArgs_SendComplete); AsyncMessageSendInfo sendInfo = (AsyncMessageSendInfo)e.UserToken; if (sendInfo.ConfirmationEvent != null) {// Signal any waiter, we sent the message. sendInfo.ConfirmationEvent.Set(); } e.Dispose(); #if Matrix_Diagnostics if (Monitor.IsReportAllowed) { Monitor.Info(this.ToString() + " message send complete [" + sendInfo.Message.ToString() + "]"); } #endif AsyncMessageSendDelegate delegateInstance = SendAsyncCompleteEvent; if (delegateInstance != null) { delegateInstance(this, sendInfo); } }
/// <summary> /// Send a message, asynchronously. /// </summary> /// <param name="message">The message being sent.</param> /// <param name="requestConfirm">Should we wait for a confirmation, the </param> /// <returns>The id of the send message, or negative value (InvalidSendIndex / -1) if send failed.</returns> public long SendAsync(object message, TimeSpan?requestConfirmTimeout) { #if Matrix_Diagnostics InstanceMonitor monitor = Monitor; if (monitor != null && monitor.IsReportAllowed) { monitor.Info(string.Format("Async sending message [{0}].", message.ToString())); } #endif System.Net.Sockets.Socket socket = _socket; if (IsConnected == false || socket == null) { #if Matrix_Diagnostics Monitor.OperationError("Communicator can not send message [" + message.ToString() + "] since not connected."); #endif return(InvalidSendIndex); } ISerializer serializer = _serializer; if (serializer == null) { return(InvalidSendIndex); } // Event used for confirmed calls ManualResetEvent sendCompleteEvent = null; if (requestConfirmTimeout.HasValue) { sendCompleteEvent = new ManualResetEvent(false); } AsyncMessageSendInfo messageSendInfo = new AsyncMessageSendInfo() { Id = PendingSendId, Socket = socket, Message = message, ConfirmationEvent = sendCompleteEvent, }; SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.UserToken = messageSendInfo; e.Completed += new EventHandler <SocketAsyncEventArgs>(SocketAsyncEventArgs_SendComplete); messageSendInfo.Stream = new MemoryStream(); if (serializer.Serialize(messageSendInfo.Stream, message) == false) { messageSendInfo.Dispose(); return(InvalidSendIndex); } e.SetBuffer(messageSendInfo.Stream.GetBuffer(), 0, (int)messageSendInfo.Stream.Length); if (messageSendInfo.Socket.SendAsync(e) == false) { messageSendInfo.Dispose(); } // Reaquire the event, to lessen the chance of [ObjectDisposedException] // when the connection is not established and we get errors on complete instantly. sendCompleteEvent = messageSendInfo.ConfirmationEvent; if (sendCompleteEvent != null) { try { if (sendCompleteEvent.WaitOne(requestConfirmTimeout.Value) == false) { #if Matrix_Diagnostics Monitor.OperationError("Communicator could not confirm message sent in assigned timeout."); #endif return(InvalidSendIndex); } } catch (ObjectDisposedException) { #if Matrix_Diagnostics Monitor.OperationError("Communicator could not confirm message sent in assigned timeout, due to event disposed."); #endif return(InvalidSendIndex); } } return(messageSendInfo.Id); }
/// <summary> /// Send a message, asynchronously. /// </summary> /// <param name="message">The message being sent.</param> /// <param name="requestConfirm">Should we wait for a confirmation, the </param> /// <returns>The id of the send message, or negative value (InvalidSendIndex / -1) if send failed.</returns> public long SendAsync(object message, TimeSpan? requestConfirmTimeout) { #if Matrix_Diagnostics InstanceMonitor monitor = Monitor; if (monitor != null && monitor.IsReportAllowed) { monitor.Info(string.Format("Async sending message [{0}].", message.ToString())); } #endif System.Net.Sockets.Socket socket = _socket; if (IsConnected == false || socket == null) { #if Matrix_Diagnostics Monitor.OperationError("Communicator can not send message [" + message.ToString() + "] since not connected."); #endif return InvalidSendIndex; } ISerializer serializer = _serializer; if (serializer == null) { return InvalidSendIndex; } // Event used for confirmed calls ManualResetEvent sendCompleteEvent = null; if (requestConfirmTimeout.HasValue) { sendCompleteEvent = new ManualResetEvent(false); } AsyncMessageSendInfo messageSendInfo = new AsyncMessageSendInfo() { Id = PendingSendId, Socket = socket, Message = message, ConfirmationEvent = sendCompleteEvent, }; SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.UserToken = messageSendInfo; e.Completed += new EventHandler<SocketAsyncEventArgs>(SocketAsyncEventArgs_SendComplete); messageSendInfo.Stream = new MemoryStream(); if (serializer.Serialize(messageSendInfo.Stream, message) == false) { messageSendInfo.Dispose(); return InvalidSendIndex; } e.SetBuffer(messageSendInfo.Stream.GetBuffer(), 0, (int)messageSendInfo.Stream.Length); if (messageSendInfo.Socket.SendAsync(e) == false) { messageSendInfo.Dispose(); } // Reaquire the event, to lessen the chance of [ObjectDisposedException] // when the connection is not established and we get errors on complete instantly. sendCompleteEvent = messageSendInfo.ConfirmationEvent; if (sendCompleteEvent != null) { try { if (sendCompleteEvent.WaitOne(requestConfirmTimeout.Value) == false) { #if Matrix_Diagnostics Monitor.OperationError("Communicator could not confirm message sent in assigned timeout."); #endif return InvalidSendIndex; } } catch (ObjectDisposedException) { #if Matrix_Diagnostics Monitor.OperationError("Communicator could not confirm message sent in assigned timeout, due to event disposed."); #endif return InvalidSendIndex; } } return messageSendInfo.Id; }