Esempio n. 1
0
        /// <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;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        /// <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;
            }
        }