PRB: "System.Messaging.MessageQueueException" Error Message When You Run the MessageQueue.Send Method MSDN Sample Code or When You Run the MessageQueue.Receive Method MSDN Sample Code (828984)



The information in this article applies to:

  • Microsoft Developer Network (MSDN)
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • Microsoft Visual Basic .NET (2003)
  • Microsoft Visual Basic .NET (2002)
  • Microsoft Visual C# .NET (2003)
  • Microsoft Visual C# .NET (2002)
  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ .NET (2002)

SYMPTOMS

When you run the sample code that appears on certain Microsoft Developer Network (MSDN) Web sites, you may receive the following error message:

An unhandled exception of type 'System.Messaging.MessageQueueException' occurred in system.messaging.dll
Additional information: External component has thrown an exception.
The following MSDN Web sites are affected:

MessageQueue.Send Method

MessageQueue.Send Method (Object)

MessageQueue.Send Method (Object, MessageQueueTransaction)

MessageQueue.Receive Method

MessageQueue.Receive Method (MessageQueueTransaction)

MessageQueue.Receive Method (TimeSpan, MessageQueueTransaction)

CAUSE

The sample code that appears on these MSDN Web sites contains the following code that may cause you to receive the System.Messaging.MessageQueueException error message.

Microsoft Visual Basic .NET
myQueue.Send("My Message Data.", New _
    MessageQueueTransaction())
Microsoft Visual C# .NET
myQueue.Send("My Message Data.", new
    MessageQueueTransaction());
Microsoft Visual C++ .NET
myQueue->Send(S"My Message Data.", new MessageQueueTransaction());
You receive the error message because the call to the myQueue.Send method uses a MessageQueueTransaction object without starting a transaction. Additionally, even if you start a transaction before calling the myQueue.Send method, your application may wait indefinitely to receive the sent message. However, your application does not receive a sent message unless the corresponding transaction is committed.

Note The MessageQueue.Send(Object, MessageQueueTransaction) method applies only to transactional queues. Therefore, you receive the error message that is mentioned in the "Symptoms" section only if you use transactional queues.

RESOLUTION

To resolve this problem, start a transaction, and then commit this transaction after sending a message. To do this, follow these steps:
  1. In your MyNewQueue class file, locate the following code:

    Visual Basic .NET
    myQueue.Send("My Message Data.", New _
        MessageQueueTransaction())
    Visual C# .NET
    myQueue.Send("My Message Data.", new
        MessageQueueTransaction());
    Visual C++ .NET
    myQueue->Send(S"My Message Data.", new MessageQueueTransaction());
  2. Replace the code that you located in step 1 with the following code:

    Visual Basic .NET
    ' Create a MessageQueueTransaction object.
    Dim MyTransaction As New MessageQueueTransaction()
    ' Start a transaction.
    MyTransaction.Begin()
    ' Send the data as part of a transaction.
    myQueue.Send("My Message Data.", MyTransaction)
    ' Commit the transaction.
    MyTransaction.Commit()
    Visual C# .NET
    // Create a MessageQueueTransaction object.
    MessageQueueTransaction MyTransaction = new MessageQueueTransaction();
    // Start a transaction.
    MyTransaction.Begin();
    // Send the data as part of a transaction.
    myQueue.Send("My Message Data.", MyTransaction);
    // Commit the transaction.
    MyTransaction.Commit();
    Visual C++ .NET
    // Create a MessageQueueTransaction object.
    MessageQueueTransaction* MyTransaction = new MessageQueueTransaction();
    // Start a transaction.
    MyTransaction->Begin();
    // Send the data as part of a transaction.
    myQueue->Send(S"My Message Data.", MyTransaction);
    // Commit the transaction.
    MyTransaction->Commit();
  3. On the Debug menu, click Start to run your application.

    If you use Visual Basic .NET, you notice the following textual output in the Output window that indicates that your application has successfully run.

    My Message Data.

    If you use Visual C# .NET or if you use Visual C++ .NET, you notice the previously-mentioned textual output in a console window that displays this output, and then closes.

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Create a private transactional queue that is named myTransactionalQueue.

    For additional information, click the following article numbers to view the articles in the Microsoft Knowledge Base:

    315698 HOW TO: Write to and Read from Microsoft Message Queue Server in Visual Basic .NET

    815811 HOW TO: Write to and Read from Microsoft Message Queue Server in Visual C# .NET

    Note While you create this queue, make sure that you click to select the Transactional check box in the Queue Name dialog box.
  2. Start Visual Studio .NET.
  3. Create an empty project that is named MyProject.

    To create the project, you can use Visual Basic .NET, Visual C# .NET, or Visual C++ .NET.
  4. In your project, add references to the System.dll file and to the System.Messaging.dll file.

    Note You do not have to perform this step if you are using Visual C++ .NET.
  5. If you use either Visual Basic .NET or Visual C# .NET, add a new class that is named MyNewQueue to your project. If you use Visual C++ .NET, add a new C++ file that is named MyNewQueue to your project.
  6. Replace the existing code, if any, in the MyNewQueue class file with the following code (from the MSDN Web sites):

    Note If you use Visual C++ .NET, the MyNewQueue.cpp file is empty. Therefore, if you use Visual C++ .NET, add the following Visual C++ .NET code to the MyNewQueue.cpp file.

    Visual Basic .NET
    Imports System
    Imports System.Messaging
    
    Namespace MyProject
    
    
        '/ <summary>
        '/ Provides a container class for the example.
        '/ </summary>
        Public Class MyNewQueue
    
    
            '**************************************************
            ' Provides an entry point to the application.
            ' 
            ' This example sends and then receives a message from
            ' a transactional queue.
            '**************************************************
    
            Public Shared Sub Main()
    
                ' Create a new instance of the class.
                Dim myNewQueue As New MyNewQueue()
    
                ' Send a message to a queue.
                myNewQueue.SendMessageTransactional()
    
                ' Receive a message from a queue.
                myNewQueue.ReceiveMessageTransactional()
    
                Return
    
            End Sub 'Main
    
    
            '**************************************************
            ' Sends a message to a queue.
            '**************************************************
    
            Public Sub SendMessageTransactional()
    
                ' Connect to a queue on the local computer.
                Dim myQueue As New MessageQueue(".\myTransactionalQueue")
    
                ' Send a message to the queue.
                If myQueue.Transactional = True Then
                    myQueue.Send("My Message Data.", New _
                        MessageQueueTransaction())
                End If
    
                Return
    
            End Sub 'SendMessageTransactional
    
    
            '**************************************************
            ' Receives a message that contains an Order.
            '**************************************************
    
            Public Sub ReceiveMessageTransactional()
    
                ' Connect to a transactional queue on the local computer.
                Dim myQueue As New MessageQueue(".\myTransactionalQueue")
    
                ' Set the formatter.
                myQueue.Formatter = New XmlMessageFormatter(New Type() _
                    {GetType([String])})
    
                ' Create a transaction.
                Dim myTransaction As New MessageQueueTransaction()
    
                Try
    
                    ' Start the transaction.
                    myTransaction.Begin()
    
                    ' Receive the message. 
                    Dim myMessage As Message = _
                        myQueue.Receive(myTransaction)
                    Dim myOrder As [String] = CType(myMessage.Body, _
                        [String])
    
                    ' Display the message information.
                    Console.WriteLine(myOrder)
    
                    ' Commit the transaction.
                    myTransaction.Commit()
    
    
                Catch e As MessageQueueException
    
                    ' Handle nontransactional queues.
                    If e.MessageQueueErrorCode = _
                        MessageQueueErrorCode.TransactionUsage Then
    
                        Console.WriteLine("Queue is not transactional.")
    
                    End If
    
                    ' Else catch other sources of a MessageQueueException.
    
    
                    ' Roll back the transaction.
                    myTransaction.Abort()
    
    
                    ' Catch other exceptions as required, such as 
                    ' InvalidOperationException, that are thrown when the formatter
                    ' cannot deserialize the message.
    
                End Try
    
                Return
    
            End Sub 'ReceiveMessageTransactional
    
        End Class 'MyNewQueue
    End Namespace 'MyProject
    Visual C# .NET
    using System;
    using System.Messaging;
    
    namespace MyProject
    {
    
        /// <summary>
        /// Provides a container class for the example.
        /// </summary>
        public class MyNewQueue
        {
    
            //**************************************************
            // Provides an entry point to the application.
            // 
            // This example sends and then receives a message from
            // a transactional queue.
            //**************************************************
    
            public static void Main()
            {
                // Create a new instance of the class.
                MyNewQueue myNewQueue = new MyNewQueue();
    
                // Send a message to a queue.
                myNewQueue.SendMessageTransactional();
    
                // Receive a message from a queue.
                myNewQueue.ReceiveMessageTransactional();
            
                return;
            }
    
    
            //**************************************************
            // Sends a message to a queue.
            //**************************************************
            
            public void SendMessageTransactional()
            {
                            
                // Connect to a queue on the local computer.
                MessageQueue myQueue = new 
                    MessageQueue(".\\myTransactionalQueue");
    
                // Send a message to the queue.
                if (myQueue.Transactional == true)
                {
                    myQueue.Send("My Message Data.", new 
                        MessageQueueTransaction());
                }
    
                return;
            }
    
    
            //**************************************************
            // Receives a message that contains an Order.
            //**************************************************
            
            public  void ReceiveMessageTransactional()
            {
                // Connect to a transactional queue on the local computer.
                MessageQueue myQueue = new 
                    MessageQueue(".\\myTransactionalQueue");
    
                // Set the formatter.
                myQueue.Formatter = new XmlMessageFormatter(new Type[]
                    {typeof(String)});
                
                // Create a transaction.
                MessageQueueTransaction myTransaction = new 
                    MessageQueueTransaction();
    
                try
                {
                    // Start the transaction.
                    myTransaction.Begin();
                    
                    // Receive the message. 
                    Message myMessage =    myQueue.Receive(myTransaction); 
                    String myOrder = (String)myMessage.Body;
    
                    // Display the message information.
                    Console.WriteLine(myOrder);
    
                    // Commit the transaction.
                    myTransaction.Commit();
    
                }
                
                catch (MessageQueueException e)
                {
                    // Handle nontransactional queues.
                    if (e.MessageQueueErrorCode == 
                        MessageQueueErrorCode.TransactionUsage)
                    { 
                        Console.WriteLine("Queue is not transactional.");
                    }
                    
                    // Else catch other sources of MessageQueueException.
    
                    // Roll back the transaction.
                    myTransaction.Abort();
                }
    
                // Catch other exceptions as required, such as 
                // InvalidOperationException, that are thrown when the formatter 
                // cannot deserialize the message.
    
                return;
            }
        }
    }
    Visual C++ .NET
    #using <mscorlib.dll>
    #using <system.dll>
    #using <system.messaging.dll>
    
    using namespace System;
    using namespace System::Messaging;
    
    /// <summary>
    /// Provides a container class for the example.
    /// </summary>
    __gc class MyNewQueue 
    {
        //*************************************************
        // Sends a message to a queue.
        //*************************************************
    public:
        void SendMessageTransactional() 
        {
            // Connect to a queue on the local computer.
            MessageQueue* myQueue = new MessageQueue(S".\\myTransactionalQueue");
    
            // Send a message to the queue.
            if (myQueue->Transactional == true) 
            {
                myQueue->Send(S"My Message Data.", new MessageQueueTransaction());
            }
    
            return;
        }
    
        //*************************************************
        // Receives a message that contains an Order.
        //*************************************************
    public:
        void ReceiveMessageTransactional() 
        {
            // Connect to a transactional queue on the local computer.
            MessageQueue* myQueue = new MessageQueue(S".\\myTransactionalQueue");
    
            // Set the formatter.
            Type* p __gc[] = new Type* __gc[1];
            p[0] = __typeof(String);
            myQueue->Formatter = new XmlMessageFormatter( p );
    
            // Create a transaction.
            MessageQueueTransaction* myTransaction = new MessageQueueTransaction();
    
            try 
            {
                // Start the transaction.
                myTransaction->Begin();
    
                // Receive the message. 
                Message* myMessage = myQueue->Receive(myTransaction); 
                String* myOrder = static_cast<String*>(myMessage->Body);
    
                // Display the message information.
                Console::WriteLine(myOrder);
    
                // Commit the transaction.
                myTransaction->Commit();
    
            } 
            catch (MessageQueueException* e)
            {
                // Handle nontransactional queues.
                if (e->MessageQueueErrorCode == 
                    MessageQueueErrorCode::TransactionUsage) 
                { 
                    Console::WriteLine(S"Queue is not transactional.");
                }
    
                // Else catch other sources of MessageQueueException.
    
                // Roll back the transaction.
                myTransaction->Abort();
            }
    
            // Catch other exceptions as required, such as 
            // InvalidOperationException, that are thrown when the formatter 
            // cannot deserialize the message.
    
            return;
        }
    };
    
    //*************************************************
    // Provides an entry point to the application.
    // 
    // This example sends and then receives a message from
    // a transactional queue.
    //*************************************************
    
    int main() 
    {
        // Create a new instance of the class.
        MyNewQueue* myNewQueue = new MyNewQueue();
    
        // Send a message to a queue.
        myNewQueue->SendMessageTransactional();
    
        // Receive a message from a queue.
        myNewQueue->ReceiveMessageTransactional();
    
        return 0;
    }
  7. Locate the following code in the SendMessageTransactional method or in the SendMessage method:

    Note If you use the MessageQueue.Send Method (Object) MSDN sample code that is mentioned in the "Symptoms" section, your code contains a SendMessage method. If you use the MSDN sample code that appears on any of the other MSDN Web sites that are mentioned in the "Symptoms" section, your code contains a SendMessageTransactional method.

    Visual Basic .NET
    Dim myQueue As New MessageQueue(".\myTransactionalQueue")
    Visual C# .NET
    MessageQueue myQueue = new 
        MessageQueue(".\\myTransactionalQueue");
    Visual C++ .NET
    MessageQueue* myQueue = new MessageQueue(S".\\myTransactionalQueue");
  8. Replace the code that you located in step 7 with the following code:

    Visual Basic .NET
    Dim myQueue As New MessageQueue(".\Private$\myTransactionalQueue")
    Visual C# .NET
    MessageQueue myQueue = new 
        MessageQueue(".\\Private$\\myTransactionalQueue");
    Visual C++ .NET
    MessageQueue* myQueue = new 
        MessageQueue(S".\\Private$\\myTransactionalQueue");
    Note The myQueue object now corresponds to the private transactional queue that you created in step 1.
  9. If your code contains a ReceiveMessageTransactional method, locate the following code in the ReceiveMessageTransactional method:

    Visual Basic .NET
    Dim myQueue As New MessageQueue(".\myTransactionalQueue")
    Visual C# .NET
    MessageQueue myQueue = new 
        MessageQueue(".\\myTransactionalQueue");
    Visual C++ .NET
    MessageQueue* myQueue = new MessageQueue(S".\\myTransactionalQueue");
    Note Your code will not contain a ReceiveMessageTransactional method if you use the MessageQueue.Send Method (Object) MSDN sample code.
  10. Replace the code, if any, that you located in step 9 with the following code:

    Visual Basic .NET
    Dim myQueue As New MessageQueue(".\Private$\myTransactionalQueue")
    Visual C# .NET
    MessageQueue myQueue = new 
        MessageQueue(".\\Private$\\myTransactionalQueue");
    Visual C++ .NET
    MessageQueue* myQueue = new 
        MessageQueue(S".\\Private$\\myTransactionalQueue");
    Note The myQueue object now corresponds to the private transactional queue that you created in step 1.
  11. On the Debug menu, click Start to run your application.

    Note You may receive the error message that is mentioned in the "Symptoms" section.

REFERENCES

For more information about the MessageQueue class, visit the following MSDN Web site:


Modification Type:MajorLast Reviewed:10/21/2003
Keywords:kbMsg kbProgramming kbSample kberrmsg kbcode kbprb KB828984 kbAudDeveloper