MSMQ (Microsoft消息队列)是Windows中默认可用的消息队列。作为跨计算机系统发送和接收消息的可靠方法,MSMQ提供了一个可伸缩、线程安全、简单和使用方便的队列,同时为你提供了在Windows数据库中持久化消息的机会。MSDN指出:“消息队列(MSMQ)技术使在不同时间运行的应用程序能够在可能暂时离线的异构网络和系统之间进行通信。应用程序将消息发送到队列并从队列读取消息。”

在使用MSMQ时,通常有两个不同的应用程序——发送者和接收者。当消息由发送者发送时,接收者应用程序不需要处于执行状态——消息实际上存储在由主机操作系统维护的队列中,当接收方应用程序需要它们时,这些消息就会脱离队列。

创建一个队列

你可以通过控制面板上的“打开或关闭Windows功能”选项打开你系统中的MSMQ。在系统中安装了MSMQ之后,创建队列就很简单了。只要到“我的电脑”,右击并选择管理。在“计算机管理”窗口中,你可以从“消息队列”节点创建一个新队列。还可以通过编程方式创建队列。

C#中的MSMQ

要使用MSMQ,你需要引入System.Messaging命名空间。要以编程方式创建队列,需要利用MessageQueue类的Create方法。下面的代码片段说明了这一点。

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

下面的代码清单演示了如何使用c#处理存储在消息队列中的消息。

private static List<string> ReadQueue(string path)
{
List<string> lstMessages = new List<string>();
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;
}

接下来,可以调用ReadQueue方法来检索存储在消息队列中的消息,如下面的代码片段所示。

string path = @".\Private$\IDG";
List<string> lstMessages = ReadQueue(path);

你还可以在消息队列中存储对象。例如,假设你需要将日志消息存储到队列中。日志消息存储在LogMessage类的一个实例中,该实例包含与日志消息的详细信息相关的必要属性。下面是LogMessage类——我只使用了两个属性来使它变得简单。

public class LogMessage
{
public string MessageText { get; set; }
public DateTime MessageTime { get; set; }
}

你应该修改LogMessage类,以包含其他必要的属性,例如,消息严重性等。下面的方法说明了如何将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();
}
}

下面的代码片段说明了如何创建LogMessage类的实例,向其填充数据,然后调用SendMessage方法来存储在消息队列中创建的实例。

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/article/3060115/how-to-work-with-msmq-in-c.html

最新文章

  1. Access数据库多表连接查询
  2. OC 类簇与复合
  3. 转换实例存储支持为EBS支持的AMI
  4. 十天冲刺---Day3
  5. 解决centos7中python-pip模块不存在的问题
  6. java观察者模式的实现
  7. win8.1上安装vc6
  8. 把Flume的Source设置为 Spooling directory source
  9. C++和pascal之间的通信
  10. Word文件交换的电脑打开字体、排版变化的原因和解决方法!
  11. ( ̄▽ ̄&quot;) 没钱了
  12. JDBC技术
  13. CVE-2016-10191 FFmpeg RTMP Heap Buffer Overflow 漏洞分析及利用
  14. Alpha冲刺No.2
  15. ACM Smallest Difference
  16. pytest生成测试报告-4种方法
  17. mysql5.7版本开始创建用户需要create user
  18. Lua学习----零碎知识点
  19. lxml 解析字符处理规则
  20. 05-Eclispe配置Tomcat插件

热门文章

  1. [打基础]luogu1957口算练习题——字符串基本操作
  2. Spark性能调优篇七之JVM相关参数调整
  3. Java源码赏析(六)Class&lt;T&gt; 类
  4. python装饰器学习详解-函数部分
  5. NET 5 原子操作、接口限流Semaphore以及性能测试JMeter
  6. 毕业三年,如何达到月薪30K?我想跟你聊聊!!
  7. 解决CentOS 8 Docker容器无法上网的问题
  8. mysql免安装教程
  9. sprignAOP那些术语
  10. Pytest测试框架(三):pytest fixture 用法