2012-03-28 12 views
13

Ho un MSMQ privato creato nel mio computer locale. Sto inviando messaggi alla coda usando il seguente codice C#. Quando ho cambiato la coda per essere transazionale, il messaggio non raggiunge il MSMQ. Tuttavia, non vi è alcuna eccezione generata nel metodo Send. Che cambiamento devo fare per farlo funzionare?Il messaggio non raggiunge MSMQ quando viene effettuato lo scambio

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

La mia ipotesi è che l'operazione ha bisogno di essere impegnata. http://msdn.microsoft.com/en-us/library/windows/desktop/ms701273(v=vs.85).aspx –

risposta

6

Per MSDN, ecco un esempio di utilizzo di una coda di MSMQ transazionale:

// 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(); 
    } 

Bisogna trattarlo come una transazione DB - iniziare la transazione con la creazione della nuova transazione MSMQ, e poi commettere o interrompere l'operazione.

2

La coda e il tipo di messaggio devono essere entrambi uguali: transazionale in questo caso. Se non si ottiene un'eccezione, utilizzare Negative Source Journaling nel codice per aiutare a trovare i messaggi persi.

20

Per le code che sono state create come transeunte, è necessario utilizzare la versione di Send() che include il parametro MessageQueueTransactionType. La più grande frustrazione con questo è che non genera eccezioni o errori come si è visto, ma il messaggio non si presenta mai.

Così, nel codice, modificare:

helpRequestQueue.Send(theMessage); 

a

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 

Edit: La mia risposta è solo un altro modo per farlo oltre a David.

13

Le transazioni non funzionano su non-transactional queues. Se si utilizza questo modulo:

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

in una coda non transazionale, viene visualizzato il messaggio di essere perso e non verrà generata un'eccezione. È possibile verificare se una coda è transazionale nelle proprietà per la coda nella console di gestione di Accodamento messaggi.

E 'meglio usare

queue.Send(message, MessageQueueTransactionType.Automatic) 
Problemi correlati