2012-03-28 6 views
13

gemacht wird Ich habe eine private MSMQ in meinem lokalen Computer erstellt. Ich sende Nachrichten mit folgendem C# -Code an die Warteschlange. Wenn ich die Warteschlange zu Transaktion geändert habe, erreicht die Nachricht das MSMQ nicht. In der Send-Methode wird jedoch keine Ausnahme ausgelöst. Welche Veränderung muss ich machen, damit es funktioniert?Nachricht erreicht MSMQ nicht, wenn Transaktion

using System; 
using System.Messaging; 
using System.Data; 

public partial class _Default : System.Web.UI.Page 
{ 
    //Sharing violation resulted from queue being open already for exclusive receive. 
    MessageQueue helpRequestQueue = new MessageQueue(@".\Private$\MyPrivateQueue", false); 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     bool isTransactionalQueue = false;  
     if (!System.Messaging.MessageQueue.Exists(@".\Private$\MyPrivateQueue"))  
     {  
      System.Messaging.MessageQueue.Create(@".\Private$\MyPrivateQueue", isTransactionalQueue);  
     }  
     SendMessage();  
     GetAllMessages();  
    } 


    private void SendMessage()  
    {  
     System.Messaging.Message theMessage = new System.Messaging.Message("TimeNow is "+DateTime.Now.ToString()); 

     theMessage.Label = "Lijo " + DateTime.Now.ToString(); 

     theMessage.Priority = System.Messaging.MessagePriority.Normal; 

     helpRequestQueue.Send(theMessage);  

    } 


    private void GetAllMessages() 
    {  
     DataTable messageTable = new DataTable();  
     messageTable.Columns.Add("Label");  
     messageTable.Columns.Add("Body");   


     //Set Message Filters  
     MessagePropertyFilter filter = new MessagePropertyFilter();  
     filter.ClearAll();  
     filter.Body = true;  
     filter.Label = true;  
     filter.Priority = true; 
     helpRequestQueue.MessageReadPropertyFilter = filter; 

     //Get All Messages  
     System.Messaging.Message[] messages = helpRequestQueue.GetAllMessages();  
     System.Messaging.XmlMessageFormatter stringFormatter = new System.Messaging.XmlMessageFormatter(new string[] { "System.String" }); 


     for (int index = 0; index < messages.Length; index++)  
     {  
      string test = System.Convert.ToString(messages[index].Priority); 
      messages[index].Formatter = stringFormatter;  
      messageTable.Rows.Add(new string[] {messages[index].Label,messages[index].Body.ToString() }); 

     } 


     Gridview1.DataSource = messageTable;  
     Gridview1.DataBind();  
    }  

    private void ReceiveAndProcess()  
    { 



    }   
} 
+2

Meine Vermutung zu verwenden, ist, dass die Transaktion festgeschrieben werden muss. http://msdn.microsoft.com/en-us/library/windows/desktop/ms701273(v=vs.85).aspx –

Antwort

6

Per MSDN, hier ist ein Beispiel einer Transaktions MSMQ-Warteschlange verwenden:

// Connect to a transactional queue on the local computer. 
    MessageQueue queue = new MessageQueue(".\\exampleTransQueue"); 

    // Create a new message. 
    Message msg = new Message("Example Message Body"); 

    // Create a message queuing transaction. 
    MessageQueueTransaction transaction = new MessageQueueTransaction(); 

    try 
    { 
     // Begin a transaction. 
     transaction.Begin(); 

     // Send the message to the queue. 
     queue.Send(msg, "Example Message Label", transaction); 

     // Commit the transaction. 
     transaction.Commit(); 
    } 
    catch(System.Exception e) 
    { 
     // Cancel the transaction. 
     transaction.Abort(); 

     // Propagate the exception. 
     throw e; 
    } 
    finally 
    { 
     // Dispose of the transaction object. 
     transaction.Dispose(); 
    } 

Sie haben es wie eine DB-Transaktion zu behandeln - die Transaktion beginnen, indem die neue MSMQ Transaktion erstellen, und dann Commit oder Abbruch der Operation.

2

Warteschlange und Nachrichtentyp müssen beide gleich sein - in diesem Fall transaktional. Wenn Sie keine Ausnahme erhalten, verwenden Sie in Ihrem Code Negativquellen-Journaling, um verlorene Nachrichten zu finden.

20

Für Warteschlangen, die Sie als Transaktionsgruppe erstellt haben, müssen Sie die Version von Send() verwenden, die den Parameter MessageQueueTransactionType enthält. Die größte Frustration dabei ist, dass es keine Ausnahmen oder Fehler gibt, wie Sie gesehen haben, aber die Nachricht wird einfach nicht angezeigt.

Also, in Ihrem Code ändern:

helpRequestQueue.Send(theMessage); 

zu

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 

Edit: Meine Antwort ist nur ein weiterer Weg, um es abgesehen von Davids zu tun.

13

Transaktionen funktionieren nicht auf non-transactional queues. Wenn Sie dieses Formular verwenden:

using(MessageQueueTransaction tx = new MessageQueueTransaction()) 
{ 
    tx.Begin(); 
    queue.Send(message, tx); 
    tx.Commit(); 
} 

Auf einer nicht transaktionalen Warteschlange, erscheint die Meldung verloren und keine Ausnahme ausgelöst wird. Sie können überprüfen, ob eine Warteschlange in den Eigenschaften für die Warteschlange in der Message Queuing-Verwaltungskonsole transaktional ist.

Es ist besser

queue.Send(message, MessageQueueTransactionType.Automatic) 
Verwandte Themen