Microsoft KB Archive/828984

= PRB: &quot;System.Messaging.MessageQueueException&quot; Error Message When You Run the MessageQueue.Send Method MSDN Sample Code or When You Run the MessageQueue.Receive Method MSDN Sample Code =

Article ID: 828984

Article Last Modified on 4/19/2007

-

APPLIES TO


 * MSDN 2003 Universal Edition
 * Microsoft .NET Framework 1.1
 * Microsoft .NET Framework 1.0
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft Visual C# .NET 2003 Standard Edition
 * Microsoft Visual C# .NET 2002 Standard Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition
 * Microsoft Visual C++ .NET 2002 Standard Edition

-





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

http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeue.send(vs.71).aspx

MessageQueue.Send Method (Object)

http://msdn2.microsoft.com/en-us/library/aa329510(VS.71).aspx

MessageQueue.Send Method (Object, MessageQueueTransaction)

http://msdn2.microsoft.com/en-us/library/aa329511(VS.71).aspx

MessageQueue.Receive Method

http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeue.receive(vs.71).aspx

MessageQueue.Receive Method (MessageQueueTransaction)

http://msdn2.microsoft.com/en-us/library/aa329505(VS.71).aspx

MessageQueue.Receive Method (TimeSpan, MessageQueueTransaction)

http://msdn2.microsoft.com/en-us/library/aa329508(VS.71).aspx



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(&quot;My Message Data.&quot;, New _   MessageQueueTransaction) Microsoft Visual C# .NET myQueue.Send(&quot;My Message Data.&quot;, new   MessageQueueTransaction); Microsoft Visual C++ .NET myQueue->Send(S&quot;My Message Data.&quot;, 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 &quot;Symptoms&quot; 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:   In your MyNewQueue class file, locate the following code:

Visual Basic .NET myQueue.Send(&quot;My Message Data.&quot;, New _   MessageQueueTransaction) Visual C# .NET myQueue.Send(&quot;My Message Data.&quot;, new   MessageQueueTransaction); Visual C++ .NET myQueue->Send(S&quot;My Message Data.&quot;, new MessageQueueTransaction);   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(&quot;My Message Data.&quot;, 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(&quot;My Message Data.&quot;, 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&quot;My Message Data.&quot;, MyTransaction); // Commit the transaction. MyTransaction->Commit;  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.



Steps to Reproduce the Behavior
 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.</li> Start Visual Studio .NET.</li> 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.</li> 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.</li> 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.</li>  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

'/    '/ Provides a container class for the example. '/    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(&quot;.\myTransactionalQueue&quot;)

' Send a message to the queue. If myQueue.Transactional = True Then myQueue.Send(&quot;My Message Data.&quot;, 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(&quot;.\myTransactionalQueue&quot;)

' 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(&quot;Queue is not transactional.&quot;)

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 {

///    /// Provides a container class for the example. ///    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(&quot;.\\myTransactionalQueue&quot;);

// Send a message to the queue. if (myQueue.Transactional == true) {               myQueue.Send(&quot;My Message Data.&quot;, 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(&quot;.\\myTransactionalQueue&quot;);

// 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(&quot;Queue is not transactional.&quot;); }               // 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
 * 1) using <mscorlib.dll>
 * 2) using <system.dll>
 * 3) using <system.messaging.dll>

using namespace System; using namespace System::Messaging;

/// /// Provides a container class for the example. /// __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&quot;.\\myTransactionalQueue&quot;);

// Send a message to the queue. if (myQueue->Transactional == true) {           myQueue->Send(S&quot;My Message Data.&quot;, 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&quot;.\\myTransactionalQueue&quot;);

// 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&quot;Queue is not transactional.&quot;); }

// 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; } </li>  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 &quot;Symptoms&quot; 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 &quot;Symptoms&quot; section, your code contains a SendMessageTransactional method.

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

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

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

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

Note You may receive the error message that is mentioned in the &quot;Symptoms&quot; section.</li></ol>

<div class="references_section">