消息队列(Message Queue)

1. 基本术语和概念(Basic terms and concepts

“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。…..

2. 队列类型

        公共队列     MachineNameQueueName    (在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。)    
        专用队列     MachineNamePrivate$QueueName    (不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。)
        日记队列     MachineNameQueueNameJournal$   
        计算机日记队列     MachineNameJournal$       (可选地存储发送消息的副本和从队列中移除的消息副本。每个“消息队列”客户端上的单个日记队列存储从该计算机发送的消息副本。在服务器上为每个队列创建了一个单独的日记队列。此日记跟踪从该队列中移除的消息。) 
        计算机死信队列     MachineNameDeadletter$    (存储无法传递或已过期的消息的副本。如果过期消息或无法传递的消息是事务性消息,则被存储在一种特殊的名为“事务性死信队列”的死信队列中。 )
        计算机事务性死信队列 MachineNameXactDeadletter$ 

3. 同步和异步通信

通信天生就是异步的,因为将消息发送到队列和从队列中接收消息是可以在不同的进程中完成的。

另外,可以异步执行接收操作,因为要接收消息的人可以对任何给定的队列调用(MQ.BeginPeek;  MQ.BeginReceive;MQ.EndPeek; MQ.EndReceive;) 方法,然后立即继续其他任务而不用等待答复。这与人们所了解的“同步通信”截然不同(MQ.Send; MQ.Receive;)

使用队列

1 创建消息队列

查看是否有这种队列MessageQueue.Exists(path)

没有创建并这种队列,或使用这种队列

2 发送消息

设置消息传输格式(如果没有的话,是XML格式)

发送消息

3 接受消息

接受消息Message类

这里涉及到同步 或者异步

同步

  主动方式,会同步阻塞当前线程
    Message m=Receive(); //接收同时,从队列中删除消息or  Message m=Peek();  //不删除接收到的消息

  或者 用异步方式,不会阻塞当前线程

    用要使用 BeginReceive,请创建一个处理异步操作结果的事件处理程序并将其与事件委托相关联。 BeginReceive 启动异步接收操作;消息达到队列时,将通过引发 ReceiveCompleted 事件通知 MessageQueue。 然后 MessageQueue 可通过调用 EndReceive(IAsyncResult) 来访问该消息。BeginReceive 方法立即返回,但直到调用事件处理程序时,异步操作才完成。

注册 事件---> BeginReceive –>引发事件(EndReceive访问消息, 继续BeginReceive)

public void MessageReceive()
        {
            MQ.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
            MQ.BeginReceive();

        }
        public void MyReceiveCompleted(Object source,
          ReceiveCompletedEventArgs asyncResult)
        {
            try
            {
                MessageQueue MQQ = (MessageQueue)source;
                MQQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
                Message m = MQQ.EndReceive(asyncResult.AsyncResult);
                //Console.WriteLine(m.Label);
                Console.WriteLine(m.Body);
                MQ.BeginReceive();
            }
            catch (MessageQueueException)
            {
                // Handle sources of MessageQueueException.
            }

            // Handle other exceptions.

            return;
        }
原文地址:https://www.cnblogs.com/jiaofu2012/p/3515709.html