MessageQueue more than once

I saw this error on other posts, but not for this exact situation.

I have two classes that do the same with MessageQueue. Because of this, I distracted the creation and deletion of the queue to the helper class. I get this error and I don’t see how the queue can be deleted more than once.

The messageQueue object can be deleted more than once in the MsmqHelper.DisposeQueue (MessageQueue) method

In one of the classes it is used like this:

private MessageQueue _messageQueue;

Then in the constructor of the class:

this._messageQueue = MsmqHelper.InitializeQueue();

Not that it really mattered, but for completeness, the queue is used here:

this._messageQueue.Send(workflowCreated);

And here are the Dispose methods:

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
    if (disposing == false) { return; }

    MsmqHelper.DisposeQueue(this._messageQueue);
}

And this is the code in the helper class that actually calls Dispose ():

public static void DisposeQueue(MessageQueue messageQueue)
{
    if (messageQueue != null)
    {
        messageQueue.Close();
        messageQueue.Dispose();
        messageQueue = null;
    }
}

Where is it possible for a queue to be deleted more than once in this situation?

** Change **

, . , :

, . messageQueue (this._messageQueue) . , messageQueue null null, . - (this._messageQueue) . , .

, (this._messageQueue) null . MsmqHelper.DisposeQueue(). , ref DisposeQueue() .

** 2 **

. .

public static void DisposeQueue(ref MessageQueue messageQueue)
{
    if (messageQueue == null) { return; }

    messageQueue.Close();
    messageQueue.Dispose();
    messageQueue = null;
}

** 3 - ? **

, . messageQueue.Dispose(), . , messageQueue.Close() messageQueue.Dispose() . . , Close() Dispose() .

+5
3

MessageQueue. . . , , , Close Dispose.

:

    public  void ReceiveMessage()
    {
        // Connect to the a on the local computer.
        MessageQueue myQueue = new MessageQueue(".\\myQueue");

        // Set the formatter to indicate body contains an Order.
        myQueue.Formatter = new XmlMessageFormatter(new Type[]
            {typeof(String)});

        try
        {
            // Receive and format the message. 
            Message myMessage1 = myQueue.Receive();
            Message myMessage2 = myQueue.Receive();
        }

        catch (MessageQueueException)
        {
            // Handle sources of any MessageQueueException.
        }

        // Catch other exceptions as necessary.

        finally
        {
            // Free resources.
            myQueue.Close();
        }

        return;
    }

, , , , . , MessageQueue, , , , MessageQueue .

* UPDATE * , CA CA2202 - - , . , , Close() Dispose(), . , , , , MessageQueue , , .

+2

. :

, this._messageQueue , MsmqHelper.DisposeQueue(this._messageQueue).

( messageQueue) null DisposeQueue. , " " . ( , # Call-By-Value: . , , " ".)

ref this._messageQueue = null .

+2

MessageQueue IDisposable iterface, Dispose Close(), Close() . , Dispose Close() mehod / .

Again, by stepping into an external static helper, you break up a one-time template. This is not the right way to control the lifetime of an object; You do not need to spoil the disposable template, you can just use it

And your code can be simplified as follows:

    // 1. Use static class. By the agreement, all helper classes should be static to avoid 
    // IDisposable inheritance, in example
    public static class MsmqHelper//: IDisposable
    {
        //private MessageQueue _messageQueue;

        //public MessageQueueHelper(bool workflowCreated)
        //{
        //    this._messageQueue = MsmqHelper.InitializeQueue();
        //    this._messageQueue.Send(workflowCreated);
        //}

        public static SendMessage(object workflowCreated)
        {
            // 2. If static method in static class does not takes parameters, 
            // I might be better to to implicitly call the constructor?

            // using(MessageQueue msmsq = MsmqHelper.InitializeQueue())

            using(MessageQueue msmsq = new MessageQueue())
            {
                msmq.Send(workflowCreated);
                msmq.Close(); 

                // MsmqHelper.DisposeQueue(msmq);

                // 3. You should explicitly call Close object to immediately release     
                // unmanaged resources, while managed ones will be released 
                // at next GC rounds, as soon as possible
            }
        }
        //private MessageQueue _messageQueue;

        //public void Dispose()
        //{
        //    Dispose(true);
        //    GC.SuppressFinalize(this);
        //}

        //private void Dispose(bool disposing)
        //{
    //    if (disposing == false) { return; }
    //
    //    MsmqHelper.DisposeQueue(this._messageQueue);
    //}

    //public static void DisposeQueue(MessageQueue messageQueue)
    //{
    //    if (messageQueue != null)
    //    {
    //        messageQueue.Close();
    //        messageQueue.Dispose();
    //        messageQueue = null;
    //    }
    //}
}
+1
source

All Articles