“消息队列”技术允许在不同时间运行的应用程序在可能暂时脱机的异类网络和系统之间进行通讯。应用程序发送、接收或查看(读取而不移除)队列中的消息。“消息队列”是 Windows 2000 和 Windows NT 的可选组件,而且必须单独安装。
MessageQueue 类是“消息队列”周围的包装。“消息队列”有多个版本,而且根据所使用的操作系统的不同,使用 MessageQueue 类可能导致行为上的细微差异。有关每个“消息队列”版本的特定功能的信息,请参见 MSDN 中 Platform SDK 的“What's New in Message Queuing”(“消息队列”的新增功能)主题。
MessageQueue 类提供对“消息队列”队列的引用。可以在 MessageQueue 构造函数中指定一个连接到现有资源的路径,或者可在服务器上创建新队列。在调用 Send、Peek 或 Receive 之前,必须将 MessageQueue 类的新实例与某个现有队列关联。此时,可操作该队列的属性,如 Category 和 Label。
MessageQueue 支持两种类型的消息检索:同步和异步。同步的 Peek 和 Receive 方法使进程线程用指定的间隔时间等待新消息到达队列。异步的 BeginPeek 和 BeginReceive 方法允许主应用程序任务在消息到达队列之前,在单独的线程中继续执行。这些方法通过使用回调对象和状态对象进行工作,以便在线程之间进行信息通讯。
当创建 MessageQueue 类的新实例时,并不是要创建新的“消息队列”队列。而是可使用 Create、Delete 和 Purge 方法管理服务器上的队列。
注意 与 Purge 不同,Create 和 Delete 是静态(在 Visual Basic 中为 Shared)成员,因此可以调用它们而无需创建 MessageQueue 类的新实例。
可以使用以下三种名称之一设置 MessageQueue 对象的 Path 属性:友好名称、FormatName 或 Label。友好名称由队列的 MachineName 和 QueueName 属性定义,对于公共队列为 MachineName\ QueueName,对于专用队列为 MachineName\ Private$\ QueueName。FormatName 属性允许对消息队列进行脱机访问。最后,可使用队列的 Label 属性设置队列的 Path。
using System;
using System.Messaging;
namespace MyProject
{
/// <summary>
/// Provides a container class for the example.
/// </summary>
public class MyNewQueue
{
//**************************************************
// Provides an entry point into the application.
//
// This example demonstrates several ways to set
// a queue's path.
//**************************************************
public static void Main()
{
// Create a new instance of the class.
MyNewQueue myNewQueue = new MyNewQueue();
myNewQueue.SendPublic();
myNewQueue.SendPrivate();
myNewQueue.SendByLabel();
myNewQueue.SendByFormatName();
myNewQueue.MonitorComputerJournal();
myNewQueue.MonitorQueueJournal();
myNewQueue.MonitorDeadLetter();
myNewQueue.MonitorTransactionalDeadLetter();
return;
}
// References public queues.
public void SendPublic()
{
MessageQueue myQueue = new MessageQueue(".\\myQueue");
myQueue.Send("Public queue by path name.");
return;
}
// References private queues.
public void SendPrivate()
{
MessageQueue myQueue = new
MessageQueue(".\\Private$\\myQueue");
myQueue.Send("Private queue by path name.");
return;
}
// References queues by label.
public void SendByLabel()
{
MessageQueue myQueue = new MessageQueue("Label:TheLabel");
myQueue.Send("Queue by label.");
return;
}
// References queues by format name.
public void SendByFormatName()
{
MessageQueue myQueue = new
MessageQueue("FormatName:Public=5A5F7535-AE9A-41d4" +
"-935C-845C2AFF7112");
myQueue.Send("Queue by format name.");
return;
}
// References computer journal queues.
public void MonitorComputerJournal()
{
MessageQueue computerJournal = new
MessageQueue(".\\Journal$");
while(true)
{
Message journalMessage = computerJournal.Receive();
// Process the journal message.
}
}
// References queue journal queues.
public void MonitorQueueJournal()
{
MessageQueue queueJournal = new
MessageQueue(".\\myQueue\\Journal$");
while(true)
{
Message journalMessage = queueJournal.Receive();
// Process the journal message.
}
}
// References dead-letter queues.
public void MonitorDeadLetter()
{
MessageQueue deadLetter = new
MessageQueue(".\\DeadLetter$");
while(true)
{
Message deadMessage = deadLetter.Receive();
// Process the dead-letter message.
}
}
// References transactional dead-letter queues.
public void MonitorTransactionalDeadLetter()
{
MessageQueue TxDeadLetter = new
MessageQueue(".\\XactDeadLetter$");
while(true)
{
Message txDeadLetter = TxDeadLetter.Receive();
// Process the transactional dead-letter message.
}
}
}
}