我在本地计算机上创建了一个私有MSMQ。我使用以下C#代码将消息发送到队列。当我将队列更改为事务时,消息未到达MSMQ。但是,Send方法中没有抛出异常。我需要做些什么改变才能让它发挥作用?
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()
{
}
}
答案 0 :(得分:21)
对于您已创建为transanctional的队列,必须使用包含MessageQueueTransactionType参数的Send()版本。最令人沮丧的是,它不会像你看到的那样抛出任何异常或错误,但这些消息并没有出现。
因此,在您的代码中,更改:
helpRequestQueue.Send(theMessage);
到
helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single);
编辑:除了大卫之外,我的回答只是另一种方式。
答案 1 :(得分:14)
交易不适用于non-transactional queues
。如果您使用此表单:
using(MessageQueueTransaction tx = new MessageQueueTransaction())
{
tx.Begin();
queue.Send(message, tx);
tx.Commit();
}
在非事务性队列中,消息似乎丢失,不会抛出任何异常。您可以在消息队列管理控制台中检查队列属性中的队列是否是事务性的。
最好使用
queue.Send(message, MessageQueueTransactionType.Automatic)
答案 2 :(得分:7)
Per MSDN,这是使用事务性MSMQ队列的示例:
// 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();
}
您必须将其视为数据库事务 - 通过创建新的MSMQ事务来开始事务,然后提交或中止操作。
答案 3 :(得分:2)
队列和消息类型都需要相同 - 在这种情况下是事务性的。 如果您没有收到异常,请在代码中使用Negative Source Journaling来帮助查找丢失的消息。