/// <summary> /// May throw a timeout exception if a message with the given id cannot be found. /// </summary> /// <param name="messageId"></param> public void ReturnMessageToSourceQueue(string messageId) { using (var scope = new TransactionScope()) { try { var message = queue.ReceiveById(messageId, TimeoutDuration, MessageQueueTransactionType.Automatic); var tm = MsmqUtilities.Convert(message); if (!tm.Headers.ContainsKey(Faults.HeaderKeys.FailedQ)) { Console.WriteLine("ERROR: Message does not have a header indicating from which queue it came. Cannot be automatically returned to queue."); return; } using (var q = new MessageQueue(MsmqUtilities.GetFullPath(Address.Parse(tm.Headers[Faults.HeaderKeys.FailedQ])))) q.Send(message, MessageQueueTransactionType.Automatic); Console.WriteLine("Success."); scope.Complete(); } catch (MessageQueueException ex) { if (ex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { Console.WriteLine(NoMessageFoundErrorFormat, messageId); foreach (var m in queue.GetAllMessages()) { var tm = MsmqUtilities.Convert(m); if (tm.Headers.ContainsKey(Faults.HeaderKeys.OriginalId)) { if (messageId != tm.Headers[Faults.HeaderKeys.OriginalId]) { continue; } Console.WriteLine("Found message - going to return to queue."); using (var tx = new TransactionScope(TransactionScopeOption.RequiresNew)) { using (var q = new MessageQueue( MsmqUtilities.GetFullPath( Address.Parse(tm.Headers[Faults.HeaderKeys.FailedQ])))) q.Send(m, MessageQueueTransactionType.Automatic); queue.ReceiveByLookupId(MessageLookupAction.Current, m.LookupId, MessageQueueTransactionType.Automatic); tx.Complete(); } Console.WriteLine("Success."); scope.Complete(); return; } } } } } }
/// <summary> /// Sends a message to the specified destination. /// </summary> /// <param name="m">The message to send.</param> /// <param name="destination">The address of the destination to send the message to.</param> public void Send(TransportMessage m, string destination) { var address = MsmqUtilities.GetFullPath(destination); using (var q = new MessageQueue(address, false, true, QueueAccessMode.Send)) { var toSend = new Message(); if (m.Body == null && m.BodyStream != null) { toSend.BodyStream = m.BodyStream; } else { MessageSerializer.Serialize(m.Body, toSend.BodyStream); } if (m.CorrelationId != null) { toSend.CorrelationId = m.CorrelationId; } toSend.Recoverable = m.Recoverable; if (!string.IsNullOrEmpty(m.ReturnAddress)) { toSend.ResponseQueue = new MessageQueue(MsmqUtilities.GetFullPath(m.ReturnAddress), false, true); } toSend.Label = new MessageLabel(m.WindowsIdentityName, m.IdForCorrelation).ToString(); if (m.TimeToBeReceived < MessageQueue.InfiniteTimeout) { toSend.TimeToBeReceived = m.TimeToBeReceived; } if (m.Headers != null && m.Headers.Count > 0) { using (var stream = new MemoryStream()) { _headerSerializer.Serialize(stream, m.Headers); toSend.Extension = stream.GetBuffer(); } } toSend.AppSpecific = (int)m.MessageIntent; try { int attempt = 0; while (true) { try { q.Send(toSend, GetTransactionTypeForSend()); break; } catch (MessageQueueException sendingEx) { if (sendingEx.MessageQueueErrorCode == MessageQueueErrorCode.InsufficientResources && attempt < SendAttemptCount) { Thread.Sleep(SendAttemptSleepIfFault); attempt++; continue; } throw; } } } catch (MessageQueueException ex) { if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound) { throw new ConfigurationErrorsException("The destination queue '" + destination + "' could not be found. You may have misconfigured the destination for this kind of message (" + m.Body[0].GetType().FullName + ") in the MessageEndpointMappings of the UnicastBusConfig section in your configuration file." + "It may also be the case that the given queue just hasn't been created yet, or has been deleted." , ex); } throw; } m.Id = toSend.Id; } }