-1

i have a console applicaiton . in this application i make contact with a queue. first i check to see if for example queue with name 'exampleQueue' exists or not. and if it does not exist i create it. after creating and returing the path or just returning the path . i want to attach the ReceiveCompleted event to this queue. i have two approach i can use 'using' keyword to make the queue dispoed after my work or i can just use normal way to create queue object .

in below u can see my code :

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateQueue(".\\exampleQueue", false);
            using (var queue = new MessageQueue(".\\exampleQueue"))
            {
                queue.ReceiveCompleted += MyReceiveCompleted;
                queue.BeginReceive();
            }
        }
        public static void CreateQueue(string queuePath, bool transactional)
        {
            if (!MessageQueue.Exists(queuePath))
            {
                MessageQueue.Create(queuePath, transactional);
            }
            else
            {
                Console.WriteLine(queuePath + " already exists.");
            }
        }
        private static void MyReceiveCompleted(Object source,
            ReceiveCompletedEventArgs asyncResult)
        {
            var queue = (MessageQueue)source;
            try
            {
                var msg = queue.EndReceive(asyncResult.AsyncResult);
                Console.WriteLine("Message body: {0}", (string)msg.Body);
                queue.BeginReceive();
            }
            catch (Exception ex)
            {
                var s = ex;
            }
            finally
            {
                queue.BeginReceive();
            }
            return;
        }
    }
}

the problem that i face is that whenever i use this code for create queue object

using (var queue = new MessageQueue(".\\exampleQueue"))
            {
                queue.ReceiveCompleted += MyReceiveCompleted;
                queue.BeginReceive();
            }

the MyReceiveCompleted event does not work properly . but when i use this

var queue = new MessageQueue(".\\exampleQueue");
            queue.ReceiveCompleted += MyReceiveCompleted;
            queue.BeginReceive();

every thing just work in proper way.

my question is that which approcah is the best one ? and if i choose to use the first approcah , how can i make it work ?

accept my apologize for bad typing .

jsDevia
  • 1,282
  • 4
  • 14
  • 37
  • 1
    your queue object is going to be cleaned up by the garbage collector. The using statement is causing dispose to be called immediately. Change your queue variable to be a static of the program class. Basically queue is being cleaned up before your event can fire. – Nattrass May 09 '15 at 10:50
  • tnx for ur answer . i wonder if i didnot dispose my object . is it going o be a problem in production use ? i mean lets say after 1 week o 1 month , that object is not going to affect the performance ? – jsDevia May 09 '15 at 10:53
  • Yes, the garbage collector is still going to trash your queue object at some undetermined point in the future and your ReceiveCompleted event will not fire. – Nattrass May 09 '15 at 10:54

1 Answers1

1

You can use your original approach, but you have to make sure, that the Main method is blocking inside the using statement:

static void Main(string[] args)
{
    CreateQueue(".\\exampleQueue", false);

    using (var queue = new MessageQueue(".\\exampleQueue"))
    {
        queue.ReceiveCompleted += MyReceiveCompleted;
        queue.BeginReceive();

        // here you have to insert code to block the 
        // execution of the Main method.
        // Something like:
        while(Console.ReadLine() != "exit")
        {
            // do nothing
        }
    }
}
abto
  • 1,583
  • 1
  • 12
  • 31