Reputation: 5537
I wet through this except that I added it to a windows service like this
public partial class TriggerHostProcesses : ServiceBase
{
private const string MESSAGE_QUEUE = @".\Private$\Sample Queue";
private MessageQueue _queue;
public TriggerHostProcesses()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
SendMessage("Hope This Works");
}
protected override void OnStop()
{
}
internal void start()
{
OnStart(null);
}
private void SendMessage(string message)
{
_queue = new MessageQueue(MESSAGE_QUEUE);
Message msg = new Message();
msg.Body = message;
msg.Label = "Testing " + DateTime.Now.ToString();
_queue.Send(msg,new MessageQueueTransaction());
}
}
and to get the message
partial class HostListener : ServiceBase
{
private const string MESSAGE_QUEUE = @".\Private$\Sample Queue";
private MessageQueue _queue;
public HostListener()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
var myTransaction = new MessageQueueTransaction();
var queue = new MessageQueue(MESSAGE_QUEUE);
var message = queue.Receive(new TimeSpan(0, 0, 20),myTransaction);
message.Formatter = new XmlMessageFormatter(
new String[] { "System.String,mscorlib" });
Console.WriteLine(message.Body.ToString());
}
catch(Exception ex)
{
Console.WriteLine("No Message");
}
}
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}
internal void start()
{
OnStart(null);
}
}
in my main I added this
var ServiceToRun1 = new TriggerHostProcesses();
var ServiceToRun2 = new HostListener();
if (Environment.UserInteractive)
{
// This used to run the service as a console (development phase only)
ServiceToRun1.start();
ServiceToRun2.start();
Console.WriteLine("Press Enter to terminate ...");
Console.ReadLine();
ServiceToRun1.Stop();
ServiceToRun2.Stop();
}
else
{
ServiceBase.Run(ServiceToRun1);
}
I get the exception Timeout for the requested operation has expired.
Can someone please check if they can see what the problem is?
Upvotes: 0
Views: 1223
Reputation: 5537
Here is my final product. I'm using this in a windows service. 20 s at a time to see if I have a message then do my processes.
public class MSMQueue:IQueue
{
public MSMQueue(string queueName)
{
Message_Queue = queueName;
}
public string Message_Queue { get; private set; }
public string Pop()
{
MessageQueue queue = new MessageQueue(Message_Queue);
if (queue.Transactional)
return popTransactionalQueue(queue, new TimeSpan(0, 0, 1));
else
return popNormalQueue(queue, new TimeSpan(0, 0, 1));
}
public string Pop(TimeSpan timeSpan)
{
MessageQueue myQueue = new MessageQueue(Message_Queue);
if (myQueue.Transactional)
return popTransactionalQueue(myQueue, timeSpan);
else
return popNormalQueue(myQueue, timeSpan);
}
public void Add(string message)
{
// Connect to a queue on the local computer.
MessageQueue myQueue = new MessageQueue(Message_Queue);
// Send a message to the queue.
if (myQueue.Transactional)
{
var myTransaction = new MessageQueueTransaction();
myTransaction.Begin();
myQueue.Send(message, myTransaction);
myTransaction.Commit();
}
else
myQueue.Send(message);
}
#region private methods
private string popNormalQueue(MessageQueue queue, TimeSpan timeOut)
{
var message = queue.Receive(timeOut);
message.Formatter = new XmlMessageFormatter(
new String[] { "System.String,mscorlib" });
return message.Body.ToString();
}
private string popTransactionalQueue(MessageQueue queue, TimeSpan timeOut)
{
// Set the formatter.
queue.Formatter = new XmlMessageFormatter(new Type[]
{typeof(String)});
// Create a transaction.
MessageQueueTransaction myTransaction = new
MessageQueueTransaction();
String message=string.Empty;
try
{
myTransaction.Begin();
Message myMessage = queue.Receive(timeOut, myTransaction);
message = (String)myMessage.Body;
myTransaction.Commit();
}
catch (MessageQueueException e)
{
myTransaction.Abort();
throw e;
}
return message;
}
#endregion
}
Upvotes: 0
Reputation: 7737
I don't believe you are using transactions correctly. For example, when sending a message you use:
_queue.Send(msg,new MessageQueueTransaction());
However, this does not begin or commit a transaction. Looking in MSDN the example uses the following code (edited by me):
var myTransaction = new MessageQueueTransaction();
myTransaction.Begin();
myQueue.Send("hello world", myTransaction);
myTransaction.Commit();
I don't believe your message is getting sent, and so your Receive
times out.
Similarly your receive logic doesn't seem to correctly use transactions:
myTransaction.Begin();
var myMessage = myQueue.Receive(myTransaction);
var body myOrder = (string)myMessage.Body;
myTransaction.Commit();
You should Rollback
in the event of an exception processing your messages so they can be placed back on the queue.
Upvotes: 2