[英]Processing MSMQ Message in Windows Service
I have a windows service for processing the MSMQ messages. 我有一个用于处理MSMQ消息的Windows服务。 It relies on the following logic
它依赖于以下逻辑
· There is a timer in the windows service. ·Windows服务中有一个计时器。 Every ten minute it will execute the method named “ProcessMessages”.
每隔十分钟,它将执行名为“ProcessMessages”的方法。
· Inside this method, it first creates a list of existing messageIds by calling GetAllMessages method of the queue. ·在此方法中,它首先通过调用队列的GetAllMessages方法创建现有messageIds的列表。
· For each messageId, it receives the message (using ReceiveById) and stores it into a file ·对于每个messageId,它接收消息(使用ReceiveById)并将其存储到文件中
Is there a better way to achieve the message processing? 有没有更好的方法来实现消息处理?
Reference: http://www.switchonthecode.com/tutorials/creating-a-simple-windows-service-in-csharp 参考: http : //www.switchonthecode.com/tutorials/creating-a-simple-windows-service-in-csharp
Note: The following code does not give the desired result when I made it as a service; 注意:当我将其作为服务时,以下代码未提供所需的结果; however there is no error in event viewer (I am not doing any explicit logging).
但是事件查看器中没有错误(我没有进行任何显式记录)。 It was working fine when it was a simple console app.
当它是一个简单的控制台应用程序时工作正常。 How to correct it?
怎么纠正呢? [Now it is working when I changed the accoun to "User" as shwon in the comments below]
[现在,当我在下面的评论中将会议改为“用户”时,它正在工作]
My actaul requirement is to process all messages at fixed time slots – say at 10 AM and 11 AM only (on each day). 我的行为要求是在固定的时间段处理所有消息 - 比如上午10点和上午11点(每天)。 What is the best approach to do this?
这样做的最佳方法是什么?
namespace ConsoleSwitchApp
{
class Program : ServiceBase
{
private static Timer scheduleTimer = null;
static MessageQueue helpRequestQueue = null;
static System.Messaging.XmlMessageFormatter stringFormatter = null;
static void Main(string[] args)
{
ServiceBase.Run(new Program());
}
public Program()
{
this.ServiceName = "LijosService6";
//Queue initialize
helpRequestQueue = new MessageQueue(@".\Private$\MyPrivateQueue", false);
stringFormatter = new System.Messaging.XmlMessageFormatter(new string[] { "System.String" });
//Set Message Filters
MessagePropertyFilter filter = new MessagePropertyFilter();
filter.ClearAll();
filter.Body = true;
filter.Label = true;
filter.Priority = true;
filter.Id = true;
helpRequestQueue.MessageReadPropertyFilter = filter;
//Start a timer
scheduleTimer = new Timer();
scheduleTimer.Enabled = true;
scheduleTimer.Interval = 120000;//2 mins
scheduleTimer.AutoReset = true;
scheduleTimer.Start();
scheduleTimer.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed);
}
protected static void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
ProcessMessages();
}
private static void ProcessMessages()
{
string messageString = "1";
//Message Processing
List<string> messageIdList = GetAllMessageId();
foreach (string messageId in messageIdList)
{
System.Messaging.Message messages = helpRequestQueue.ReceiveById(messageId);
//Store the message into database
messages.Formatter = stringFormatter;
string messageBody = System.Convert.ToString(messages.Body);
if (String.IsNullOrEmpty(messageString))
{
messageString = messageBody;
}
else
{
messageString = messageString + "___________" + messageBody;
}
}
//Write File
string lines = DateTime.Now.ToString();
lines = lines.Replace("/", "-");
lines = lines.Replace(":", "_");
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test" + lines + ".txt");
file.WriteLine(messageString);
file.Close();
}
private static List<string> GetAllMessageId()
{
List<string> messageIdList = new List<string>();
DataTable messageTable = new DataTable();
messageTable.Columns.Add("Label");
messageTable.Columns.Add("Body");
//Get All Messages
System.Messaging.Message[] messages = helpRequestQueue.GetAllMessages();
for (int index = 0; index < messages.Length; index++)
{
string messageId = (System.Convert.ToString(messages[index].Id));
messageIdList.Add(messageId);
messages[index].Formatter = stringFormatter;
messageTable.Rows.Add(new string[] { messages[index].Label, messages[index].Body.ToString() });
}
return messageIdList;
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
}
protected override void OnStop()
{
base.OnStop();
}
}
}
namespace ConsoleSwitchApp
{
[RunInstaller(true)]
public class MyWindowsServiceInstaller : Installer
{
public MyWindowsServiceInstaller()
{
var processInstaller = new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//set the privileges
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.DisplayName = "LijosService6";
serviceInstaller.StartType = ServiceStartMode.Manual;
//must be the same as what was set in Program's constructor
serviceInstaller.ServiceName = "LijosService6";
this.Installers.Add(processInstaller);
this.Installers.Add(serviceInstaller);
}
}
}
A nice alternative to using a timer is to use the MessageQueue.BeginReceive
method and do work in the ReceiveCompleted
event. 使用计时器的一个不错的替代方法是使用
MessageQueue.BeginReceive
方法并在ReceiveCompleted
事件中工作。 This way your code will wait until there is a message in the queue and then immediately process the message, then check for the next message. 这样,您的代码将等待队列中有消息,然后立即处理消息,然后检查下一条消息。
A short stub (a complete example in the linked MSDN article.) 短存根(链接的MSDN文章中的完整示例。)
private void Start()
{
MessageQueue myQueue = new MessageQueue(".\\myQueue");
myQueue.ReceiveCompleted +=
new ReceiveCompletedEventHandler(MyReceiveCompleted);
myQueue.BeginReceive();
}
private static void MyReceiveCompleted(Object source,
ReceiveCompletedEventArgs asyncResult)
{
try
{
MessageQueue mq = (MessageQueue)source;
Message m = mq.EndReceive(asyncResult.AsyncResult);
// TODO: Process the m message here
// Restart the asynchronous receive operation.
mq.BeginReceive();
}
catch(MessageQueueException)
{
// Handle sources of MessageQueueException.
}
return;
}
Why not to subscribe to ReceiveCompleted event? 为什么不订阅ReceiveCompleted事件? Another option, if both sender and subscriber is .Net projects you are working on, use WCF over MSMQ .
另一个选择,如果发件人和订阅者都是您正在处理的.Net项目,则使用WCF而不是MSMQ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.