3
\$\begingroup\$

Please review the code below and provide constructive feedback to improve.

Multiple threads call the SendMessageToMSMQ method to send messages to a msmq queue.

Occassionally messageQueue.Send(sendMsg); throws insufficent resources exception. Dont know why it's happening. Storage is not an issue, since I have checked the disk and the queue properties. There is no limit on queue storage. I doubt on the number of msmq connections being opened and closed...

Any help appreciated. Thank you.

     using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{

    /// <summary>
    /// program assumes the msmq private queue with name "queueName" exists
    /// </summary>
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            Parallel.For(0, 10000, index =>
            {
                MSMQSender.SendMessageToMSMQ<msmqMessageObject>(new msmqMessageObject { Name = index.ToString(), Value = index.ToString(), count = index });
            }
            );
        }
    }


    public class MSMQSender
    {
        private static object lockObject = new object();
        private static ConcurrentQueue<msmqMessageObject> concurrentQueue = new ConcurrentQueue<msmqMessageObject>();

        public static void SendMessageToMSMQ<T>(T msmqMessageObject1)
        {
            if (Monitor.TryEnter(lockObject))
            {
                try
                {
                    using (var messageQueue = new MessageQueue())
                    {
                        messageQueue.Path = string.Format(@"Formatname:DIRECT=OS:.\Private$\{0}", "queueName");

                        using (var sendMsg = new Message())
                        {
                            sendMsg.Recoverable = false;
                            sendMsg.Body = msmqMessageObject1;
                            messageQueue.Send(sendMsg);
                        }

                        messageQueue.Close();
                    }

                    if (concurrentQueue.Count > 0)
                    {
                        msmqMessageObject msmqMessageObject2;
                        while (concurrentQueue.TryDequeue(out msmqMessageObject2))
                        {
                            try
                            {
                                using (var messageQueue = new MessageQueue())
                                {
                                    messageQueue.Path = string.Format(@"Formatname:DIRECT=OS:.\Private$\{0}", "queueName");
                                    using (var sendMsg = new Message())
                                    {
                                        sendMsg.Recoverable = false;
                                        sendMsg.Body = msmqMessageObject2;
                                        messageQueue.Send(sendMsg);
                                    }

                                    messageQueue.Close();
                                }
                            }
                            catch (Exception ex)
                            {
                                concurrentQueue.Enqueue(msmqMessageObject1 as msmqMessageObject);
                                if (concurrentQueue.Count > 10)
                                {
                                    //todo: log error
                                }
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    concurrentQueue.Enqueue(msmqMessageObject1 as msmqMessageObject);
                    if (concurrentQueue.Count > 10)
                    {
                        //todo: log error
                    }
                }
                finally
                {
                    Monitor.Exit(lockObject);
                }
            }
            else
            {
                concurrentQueue.Enqueue(msmqMessageObject1 as msmqMessageObject);
            }
        }
    }

    public class msmqMessageObject
    {
        public string Name;

        public string Value;

        public int count;
    }
}
\$\endgroup\$

closed as off-topic by yuri, t3chb0t, Oh My Goodness, pacmaninbw, Vogel612 Jun 15 at 20:55

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – yuri, t3chb0t, Oh My Goodness, pacmaninbw, Vogel612
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ Code Review is a community where programmers peer-review your working code. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review. -> Do you have an idea why you get the exception occasionaly? \$\endgroup\$ – dfhwze Jun 14 at 21:39
  • \$\begingroup\$ The code works correctly. Issue is with MSMQ System.Messaging.MessageQueueException Source: System.Messaging Message: Insufficient resources to perform operation. Stack Trace: at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType) \$\endgroup\$ – Sam Jun 14 at 21:41
  • 1
    \$\begingroup\$ I am sorry, but I don't see how 'correctly working' and 'issue' can be symbiotes. \$\endgroup\$ – dfhwze Jun 14 at 21:48
  • \$\begingroup\$ Created a complete example. \$\endgroup\$ – Sam Jun 15 at 5:08