MSMQ 是 Windows 自带的消息队列,它提供了在多机器,多系统之间实现可靠的消息互联,MSMQ 支持可扩展,线程安全,使用简单等强势特性。
MSDN 上说:消息队列技术使不同时刻运行的程序可以在异构网络或者异构系统中进行交互,即使对方不在线也没有关系,应用程序仅关心如何从队列中读取或写入消息。
通常和 MSMQ 交互的应用程序有两种角色,发布者
和 消费者
,发布者应用程序将消息发送后,不要求消费者应用程序保持备战状态,实际上这个消息是被送到 操作系统维护的 消息队列 中,供后续某个时刻需要此消息的 接收者应用程序 消费。
创建队列
可以在 Windows 控制面板上通过 Turn Windows features on or off
选项进行 MSMQ 的安装,一旦 MSMQ 安装好之后,接下来就可以创建队列了,你可以在 Computer Management
上的 Message Queuing
节点上可视化创建,也可以通过编程的方式创建,本篇就来讨论后面这种方式。
编程创建 MSMQ
先引用 System.Messaging
命名空间,然后使用 MessageQueue.Create
创建消息队列,下面的代码展示了如何实现。
MessageQueue.Create(@".\Private$\IDG");
队列创建好之后,接下来就可以向其发送 message 了,如下代码所示:
MessageQueue.Create(@".\Private$\IDG");
messageQueue = new MessageQueue(@".\Private$\IDG");
messageQueue.Label = "This is a test queue.";
messageQueue.Send("This is a test message.", "IDG");
有一点要注意,在发送消息之前,你需要检查队列是否存在,如果不存在,你必须要先创建一个,如果存在则不必再创建,下面的代码展示了如何去实现。
static void Main(string[] args)
{
MessageQueue messageQueue = null;
string description = "This is a test queue.";
string message = "This is a test message.";
string path = @".\Private$\IDG";
try
{
if (MessageQueue.Exists(path))
{
messageQueue = new MessageQueue(path);
messageQueue.Label = description;
}
else
{
MessageQueue.Create(path);
messageQueue = new MessageQueue(path);
messageQueue.Label = description;
}
messageQueue.Send(message);
}
catch
{
throw;
}
finally
{
messageQueue.Dispose();
}
}
上面是消息的发送,接下来再看一下如何从 消息队列 中获取消息,代码如下:
private static List ReadQueue(string path)
{
List lstMessages = new List();
using (MessageQueue messageQueue = new MessageQueue(path))
{
System.Messaging.Message[] messages = messageQueue.GetAllMessages();
foreach (System.Messaging.Message message in messages)
{
message.Formatter = new XmlMessageFormatter(new String[] { "System.String, mscorlib" });
string msg = message.Body.ToString();
lstMessages.Add(msg);
}
}
return lstMessages;
}
上面的案例演示的是向消息队列中塞入 string 类型,其实还可以塞入 model ,为了简单起见,我定义了一个只有两个属性的 LogMessage 类,如下代码所示:
public class LogMessage
{
public string MessageText { get; set; }
public DateTime MessageTime { get; set; }
}
下面的代码展示了如何将 logMessage 实例送入到 消息队列 中。
private static void SendMessage(string queueName, LogMessage msg)
{
MessageQueue messageQueue = null;
if (!MessageQueue.Exists(queueName)) messageQueue = MessageQueue.Create(queueName);
else messageQueue = new MessageQueue(queueName);
try
{
messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(LogMessage) });
messageQueue.Send(msg);
}
catch
{
//Write code here to do the necessary error handling.
}
finally
{
messageQueue.Close();
}
}
接下来看看 SendMessage 方法是如何对 LogMessage 进行填充数据的,如下代码所示:
LogMessage msg = new LogMessage()
{
MessageText = "This is a test message.",
MessageTime = DateTime.Now
};
SendMessage(@".\Private$\IDGLog", msg);
然后再看看看如何从 消息队列 中读取 LogMessage 。
private static LogMessage ReceiveMessage(string queueName)
{
if (!MessageQueue.Exists(queueName)) return null;
MessageQueue messageQueue = new MessageQueue(queueName);
LogMessage logMessage = null;
try
{
messageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(LogMessage) });
logMessage = (LogMessage)messageQueue.Receive().Body;
}
catch { }
finally
{
messageQueue.Close();
}
return logMessage;
}
译文链接: https://www.infoworld.com/art...
更多高质量干货:参见我的 GitHub: csharptranslate