ASP.NET中进行消息处理(MSMQ) 二

摘要:
在我的上一篇文章“ASP.NET 1中的消息处理”中,我对MSMQ做了一个通俗的介绍。最后,我以发送普通文本消息和复杂对象消息为例介绍了消息队列的使用。在此基础上,本文继续介绍了MSMQ的相关知识,最后通过一个示例程序分析了MSMQ在实际项目开发中的应用。
      在我上一篇文章《ASP.NET中进行消息处理(MSMQ)一》里对MSMQ做了个通俗的介绍,最后以发送普通文本消息和复杂的对象消息为例介绍了消息队列的使用。 本文在此基础上继续介绍MSMQ的相关知识点,最后还是通过一个示例程序来分析MSMQ在实际项目开发中的应用。

建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:《ASP.NET中进行消息处理(MSMQ)一》。

一、消息传递的优先级
      在MSMQ中消息在队列里传输是分有优先级的,这里我就以实例的形式介绍下关于优先级的使用,优先级一共有七种,MessagePriority枚举里全部进行了封装。因这里只作程序演示就不一一列举出,仅用了HighestNormal两种类型,关于消息队列上进行消息传输的七种优先级大家可以参考我下面提供的MessagePriority枚举源代码定义。
      那么在发送消息的时候怎么指定消息的优先级呢?在Message对象里封装有一个属性Priority,接受一个枚举MessagePriority类型的值来设置消息传输的优先级。如下:
1ASP.NET中进行消息处理(MSMQ) 二第1张System.Messaging.Message message = new System.Messaging.Message();
2ASP.NET中进行消息处理(MSMQ) 二第1张message.Priority = MessagePriority.Highest;  //最高消息优先级

      下面来看看一个在消息传输中使用优先级的示例程序,通过示例程序会学习得更明白。示例程序界面:
      ASP.NET中进行消息处理(MSMQ) 二第3张

      根据界面可知,提供了消息名字,消息优先级和消息内容三个输入项,前面曾经说过,这里为了方便演示就仅用了HighestNormal两种类型,当点击发送消息的时候就通过是否选择优先级来设置消息的优先级,代码如下:
 1ASP.NET中进行消息处理(MSMQ) 二第1张private void btnSend_Click(object sender, EventArgs e)
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张    //连接到本地的专用队列myQueue
 4ASP.NET中进行消息处理(MSMQ) 二第8张    MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue");
 5ASP.NET中进行消息处理(MSMQ) 二第8张    System.Messaging.Message message = new System.Messaging.Message();
 6ASP.NET中进行消息处理(MSMQ) 二第8张    message.Label = tbName.Text;
 7ASP.NET中进行消息处理(MSMQ) 二第8张    message.Body = tbContext.Text;
 8ASP.NET中进行消息处理(MSMQ) 二第8张
 9ASP.NET中进行消息处理(MSMQ) 二第8张    if (cbPriority.Checked)
10ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
11ASP.NET中进行消息处理(MSMQ) 二第8张        message.Priority = MessagePriority.Highest;
12ASP.NET中进行消息处理(MSMQ) 二第19张    }

13ASP.NET中进行消息处理(MSMQ) 二第8张    else
14ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
15ASP.NET中进行消息处理(MSMQ) 二第8张        message.Priority = MessagePriority.Normal;
16ASP.NET中进行消息处理(MSMQ) 二第19张    }

17ASP.NET中进行消息处理(MSMQ) 二第8张    myQueue.Send(message);
18ASP.NET中进行消息处理(MSMQ) 二第8张    MessageBox.Show("成功发送消息到队列");
19ASP.NET中进行消息处理(MSMQ) 二第28张}
     这里我们可以向队列里发送两条消息,以便后面测试读取方法,发送两条消息到队列,此时,从队列消息中可以看到:
            ASP.NET中进行消息处理(MSMQ) 二第29张
     "刷新队列"实质上就是把队列里的消息全部读取出来,具体的实现在《ASP.NET中进行消息处理(MSMQ)一》里已经作了详细的介绍,这里就不在多说,看看下面的代码:
 1ASP.NET中进行消息处理(MSMQ) 二第1张private void DisplayMessage()
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张        ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张            //连接到本地队列
 4ASP.NET中进行消息处理(MSMQ) 二第8张            MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue");
 5ASP.NET中进行消息处理(MSMQ) 二第8张            myQueue.MessageReadPropertyFilter.Priority = true;
 6ASP.NET中进行消息处理(MSMQ) 二第8张            DataTable messageTable = new DataTable();
 7ASP.NET中进行消息处理(MSMQ) 二第8张            messageTable.Columns.Add("名字");
 8ASP.NET中进行消息处理(MSMQ) 二第8张            messageTable.Columns.Add("消息内容");
 9ASP.NET中进行消息处理(MSMQ) 二第8张            messageTable.Columns.Add("优先级");
10ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张            XmlMessageFormatter formatter = new XmlMessageFormatter(new string[] ASP.NET中进行消息处理(MSMQ) 二第7张"System.String" });
11ASP.NET中进行消息处理(MSMQ) 二第8张            try
12ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张            ASP.NET中进行消息处理(MSMQ) 二第7张{
13ASP.NET中进行消息处理(MSMQ) 二第8张                //从队列中接收消息
14ASP.NET中进行消息处理(MSMQ) 二第8张                System.Messaging.Message[] messages = myQueue.GetAllMessages();
15ASP.NET中进行消息处理(MSMQ) 二第8张                for (int index = 0; index < messages.Length; index++)
16ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张                ASP.NET中进行消息处理(MSMQ) 二第7张{
17ASP.NET中进行消息处理(MSMQ) 二第8张                    messages[index].Formatter = formatter;
18ASP.NET中进行消息处理(MSMQ) 二第8张
19ASP.NET中进行消息处理(MSMQ) 二第8张                    string label = messages[index].Label;
20ASP.NET中进行消息处理(MSMQ) 二第8张                    string body = messages[index].Body.ToString();
21ASP.NET中进行消息处理(MSMQ) 二第8张                    string priority = messages[index].Priority.ToString();
22ASP.NET中进行消息处理(MSMQ) 二第8张
23ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张                    messageTable.Rows.Add(new string[] ASP.NET中进行消息处理(MSMQ) 二第7张{ label, body, priority });
24ASP.NET中进行消息处理(MSMQ) 二第19张                }

25ASP.NET中进行消息处理(MSMQ) 二第8张                this.dgvMessage.DataSource = messageTable;
26ASP.NET中进行消息处理(MSMQ) 二第19张            }

27ASP.NET中进行消息处理(MSMQ) 二第8张            catch (MessageQueueException e1)
28ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张            ASP.NET中进行消息处理(MSMQ) 二第7张{
29ASP.NET中进行消息处理(MSMQ) 二第8张                MessageBox.Show(e1.Message);
30ASP.NET中进行消息处理(MSMQ) 二第19张            }

31ASP.NET中进行消息处理(MSMQ) 二第28张        }

32ASP.NET中进行消息处理(MSMQ) 二第1张    }
      这里封装了一方法,专门负责从队列里读取全部消息并绑定在DataGridView控件上,这里我们只需要在按扭Click事件里调用这方法就OK。
1ASP.NET中进行消息处理(MSMQ) 二第1张private void btnRec_Click(object sender, EventArgs e)
2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
3ASP.NET中进行消息处理(MSMQ) 二第8张    DisplayMessage();
4ASP.NET中进行消息处理(MSMQ) 二第28张}
     这就完成了给消息设置优先级的消息传输的应用,最终的测试结果如下:
       ASP.NET中进行消息处理(MSMQ) 二第80张

注:要完成以上应用还需注意一点,由于消息的优先级是枚举类型,在直接messages[index].Priority.ToString();这种方式来获取优先级转化到字符串的时候,他需要一个过滤器(Filter),否则会抛出一个InvalidCastExceptionle类型的异常,异常信息"接收消息时未检索到属性 Priority。请确保正确设置了 PropertyFilter。",要解决这问题只需要把消息对象的MessageReadPropertyFilter(过滤器) 的Priority设置为true就OK了。见上面代码里!^.^

MessagePriority枚举源代码定义详细如下:
 1ASP.NET中进行消息处理(MSMQ) 二第1张// 摘要:
 2ASP.NET中进行消息处理(MSMQ) 二第1张//     指定消息队列在消息传递到队列的过程中应用于该消息的优先级,以及指定何时将消息插入目标队列。
 3ASP.NET中进行消息处理(MSMQ) 二第1张public enum MessagePriority
 4ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 5ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
 6ASP.NET中进行消息处理(MSMQ) 二第8张    //     最低消息优先级。
 7ASP.NET中进行消息处理(MSMQ) 二第8张    Lowest = 0,
 8ASP.NET中进行消息处理(MSMQ) 二第8张    //
 9ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
10ASP.NET中进行消息处理(MSMQ) 二第8张    //     位于 Low 和 Lowest 消息优先级之间。
11ASP.NET中进行消息处理(MSMQ) 二第8张    VeryLow = 1,
12ASP.NET中进行消息处理(MSMQ) 二第8张    //
13ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
14ASP.NET中进行消息处理(MSMQ) 二第8张    //     低消息优先级。
15ASP.NET中进行消息处理(MSMQ) 二第8张    Low = 2,
16ASP.NET中进行消息处理(MSMQ) 二第8张    //
17ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
18ASP.NET中进行消息处理(MSMQ) 二第8张    //     普通消息优先级。
19ASP.NET中进行消息处理(MSMQ) 二第8张    Normal = 3,
20ASP.NET中进行消息处理(MSMQ) 二第8张    //
21ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
22ASP.NET中进行消息处理(MSMQ) 二第8张    //     位于 System.Messaging.MessagePriority.High 和 System.Messaging.MessagePriority.Normal
23ASP.NET中进行消息处理(MSMQ) 二第8张    //     消息优先级之间。
24ASP.NET中进行消息处理(MSMQ) 二第8张    AboveNormal = 4,
25ASP.NET中进行消息处理(MSMQ) 二第8张    //
26ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
27ASP.NET中进行消息处理(MSMQ) 二第8张    //     高消息优先级。
28ASP.NET中进行消息处理(MSMQ) 二第8张    High = 5,
29ASP.NET中进行消息处理(MSMQ) 二第8张    //
30ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
31ASP.NET中进行消息处理(MSMQ) 二第8张    //     位于 Highest 和 High 消息优先级之间。
32ASP.NET中进行消息处理(MSMQ) 二第8张    VeryHigh = 6,
33ASP.NET中进行消息处理(MSMQ) 二第8张    //
34ASP.NET中进行消息处理(MSMQ) 二第8张    // 摘要:
35ASP.NET中进行消息处理(MSMQ) 二第8张    //     最高消息优先级。
36ASP.NET中进行消息处理(MSMQ) 二第8张    Highest = 7,
37ASP.NET中进行消息处理(MSMQ) 二第28张}

二、事务性消息处理
      事务我想大家对这个词应该都不会陌生,在操作数据库的时候经常都会用到事务,确保操作成功,要么全部完成(成功),要么全部不完成(失败)。在MSMQ中利用事务性处理,可以确保事务中的消息按照顺序传送,只传送一次,并且从目的队列成功地被检索。
     那么,在MSMQ上使用事务性处理怎么实现呢?可以通过创建MessageQueueTransation类的实例并将其关联到MessageQueue组件的实例来执行,执行事务的Begin方法,并将其实例传递到收发方法。然后,调用Commit以将事务的更改保存到目的队列。
     创建事务性消息和普通的消息有一点小小的区别,大家可从下图上体会到:
                                  ASP.NET中进行消息处理(MSMQ) 二第120张
     通过代码方式建立事务性消息队列只在Create方法的参数上动动手脚就OK,详细如下:
1ASP.NET中进行消息处理(MSMQ) 二第1张//创建普通的专用消息队列
2ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueue myMessage = MessageQueue.Create(@".\private$\myQueue");
3ASP.NET中进行消息处理(MSMQ) 二第1张//创建事务性的专用消息队列
4ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueue myTranMessage =MessageQueue.Create(@".\private$\myQueueTrans"true);

      启动了事务,那么在发送和接收消息的时候肯定是与原来有一定的差别的,这里我就不做详细介绍,下面给出示意性代码,有兴趣的朋友可以直接下载本文示例程序代码了解更多。

普通的消息发送示意性代码:
1ASP.NET中进行消息处理(MSMQ) 二第1张//连接到本地的队列
2ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueue myQueue = new MessageQueue(".\\private$\\myQueue");
3ASP.NET中进行消息处理(MSMQ) 二第1张Message myMessage = new Message();
4ASP.NET中进行消息处理(MSMQ) 二第1张myMessage.Body = "消息内容";
5ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张myMessage.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(string) });
6ASP.NET中进行消息处理(MSMQ) 二第1张//发送消息到队列中
7ASP.NET中进行消息处理(MSMQ) 二第1张myQueue.Send(myMessage);
启动了事务后的消息发送示意性代码:
 1ASP.NET中进行消息处理(MSMQ) 二第1张//连接到本地的队列
 2ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueue myQueue = new MessageQueue(".\\private$\\myQueueTrans");
 3ASP.NET中进行消息处理(MSMQ) 二第1张
 4ASP.NET中进行消息处理(MSMQ) 二第1张Message myMessage = new Message();
 5ASP.NET中进行消息处理(MSMQ) 二第1张myMessage.Body = "消息内容";
 6ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张myMessage.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(string) });
 7ASP.NET中进行消息处理(MSMQ) 二第1张
 8ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueueTransaction myTransaction = new MessageQueueTransaction();
 9ASP.NET中进行消息处理(MSMQ) 二第1张//启动事务
10ASP.NET中进行消息处理(MSMQ) 二第1张myTransaction.Begin();
11ASP.NET中进行消息处理(MSMQ) 二第1张//发送消息到队列中
12ASP.NET中进行消息处理(MSMQ) 二第1张myQueue.Send(myMessage, myTransaction);  //加了事务
13ASP.NET中进行消息处理(MSMQ) 二第1张//提交事务
14ASP.NET中进行消息处理(MSMQ) 二第1张myTransaction.Commit();
15ASP.NET中进行消息处理(MSMQ) 二第1张Console.WriteLine("消息发送成功!");

读取消息示意性代码:
 1ASP.NET中进行消息处理(MSMQ) 二第1张//连接到本地队列
 2ASP.NET中进行消息处理(MSMQ) 二第1张MessageQueue myQueue = new MessageQueue(".\\private$\\myQueueTrans");
 3ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张myQueue.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(string) });
 4ASP.NET中进行消息处理(MSMQ) 二第1张if (myQueue.Transactional)
 5ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 6ASP.NET中进行消息处理(MSMQ) 二第8张    MessageQueueTransaction myTransaction = new MessageQueueTransaction();
 7ASP.NET中进行消息处理(MSMQ) 二第8张    //启动事务
 8ASP.NET中进行消息处理(MSMQ) 二第8张    myTransaction.Begin();
 9ASP.NET中进行消息处理(MSMQ) 二第8张    //从队列中接收消息
10ASP.NET中进行消息处理(MSMQ) 二第8张    Message myMessage = myQueue.Receive(myTransaction);
11ASP.NET中进行消息处理(MSMQ) 二第8张    string context = myMessage.Body as string//获取消息的内容
12ASP.NET中进行消息处理(MSMQ) 二第8张    myTransaction.Commit();
13ASP.NET中进行消息处理(MSMQ) 二第8张    Console.WriteLine("消息内容为:" + context);
14ASP.NET中进行消息处理(MSMQ) 二第28张}

三、异步消息处理
      在MSMQ中对消息的操作分有同步化操作和异步化操作两种,那两者到底有何区别呢?简单的说同步化操作就是一项操作没有完成前它将堵塞整个进程直到操作完成,下一项操作才会执行。所谓异步化操作则相反,不会堵塞启动操作的调用线程。如果你想在检索消息但不想堵塞其他程序的执行,则可使用异步消息处理。
     在MSMQ中异步接收消息使用BeginReceive方法和EndReceive方法来标记操作的开始和结束,异步查看消息则使用BeginPeek和EndPeek两个方法来标记异步读取的开始和结束。同时,异步接收和查看消息还可以指定超时时间,关于这点我在后续文章里再做详细的介绍,有兴趣的朋友可以关注。
      这里我将使用《ASP.NET中进行消息处理(MSMQ)一》一文里使用过的Book类来作为消息传输,没阅读过的朋友请先阅读这篇文章,了解Book类的结构。下面提供了一个示例,创建队列和发送消息到队列在前面我们已经使用多次了这里就不贴代码了,发送消息这里与第一篇文章中介绍如何发送一个复杂的类型信息到队列比,只是多了事务处理,详细如下:
 1ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张/**//// <summary>
 2ASP.NET中进行消息处理(MSMQ) 二第8张/// 发送消息到队列
 3ASP.NET中进行消息处理(MSMQ) 二第28张/// </summary>

 4ASP.NET中进行消息处理(MSMQ) 二第1张private static void SendMessage()
 5ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 6ASP.NET中进行消息处理(MSMQ) 二第8张    MessageQueue myQueue = new MessageQueue(".\\private$\\myAsyncQueue");
 7ASP.NET中进行消息处理(MSMQ) 二第8张    if (myQueue.Transactional)
 8ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
 9ASP.NET中进行消息处理(MSMQ) 二第8张        Book book = new Book();
10ASP.NET中进行消息处理(MSMQ) 二第8张        book.BookId = 1001;
11ASP.NET中进行消息处理(MSMQ) 二第8张        book.BookName = "ASP.NET";
12ASP.NET中进行消息处理(MSMQ) 二第8张        book.BookAuthor = "ZhangSan";
13ASP.NET中进行消息处理(MSMQ) 二第8张        book.BookPrice = 88.88;
14ASP.NET中进行消息处理(MSMQ) 二第8张        Message message = new Message(book);
15ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        message.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(MSMQ.Async.Book) });
16ASP.NET中进行消息处理(MSMQ) 二第8张
17ASP.NET中进行消息处理(MSMQ) 二第8张        MessageQueueTransaction myTransaction = new MessageQueueTransaction();
18ASP.NET中进行消息处理(MSMQ) 二第8张        myTransaction.Begin();
19ASP.NET中进行消息处理(MSMQ) 二第8张        myQueue.Send(message, myTransaction);
20ASP.NET中进行消息处理(MSMQ) 二第8张        myTransaction.Commit();
21ASP.NET中进行消息处理(MSMQ) 二第8张        Console.WriteLine("消息成功发送到队列!");
22ASP.NET中进行消息处理(MSMQ) 二第19张    }

23ASP.NET中进行消息处理(MSMQ) 二第28张}

异步接收消息:
 1ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张/**//// <summary>
 2ASP.NET中进行消息处理(MSMQ) 二第8张/// 异步接收消息
 3ASP.NET中进行消息处理(MSMQ) 二第28张/// </summary>

 4ASP.NET中进行消息处理(MSMQ) 二第1张private static void AsyncReceiveMessage()
 5ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 6ASP.NET中进行消息处理(MSMQ) 二第8张    MessageQueue myQueue = new MessageQueue(".\\private$\\myAsyncQueue");
 7ASP.NET中进行消息处理(MSMQ) 二第8张    if (myQueue.Transactional)
 8ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
 9ASP.NET中进行消息处理(MSMQ) 二第8张        MessageQueueTransaction myTransaction = new MessageQueueTransaction();
10ASP.NET中进行消息处理(MSMQ) 二第8张        //这里使用了委托,当接收消息完成的时候就执行MyReceiveCompleted方法
11ASP.NET中进行消息处理(MSMQ) 二第8张        myQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
12ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        myQueue.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(MSMQ.Async.Book) });
13ASP.NET中进行消息处理(MSMQ) 二第8张        myTransaction.Begin();
14ASP.NET中进行消息处理(MSMQ) 二第8张        myQueue.BeginReceive();//启动一个没有超时时限的异步操作
15ASP.NET中进行消息处理(MSMQ) 二第8张        signal.WaitOne();
16ASP.NET中进行消息处理(MSMQ) 二第8张        myTransaction.Commit();
17ASP.NET中进行消息处理(MSMQ) 二第19张    }

18ASP.NET中进行消息处理(MSMQ) 二第28张}

 1ASP.NET中进行消息处理(MSMQ) 二第1张private static void MyReceiveCompleted(Object source, ReceiveCompletedEventArgs asyncResult)
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张    try
 4ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
 5ASP.NET中进行消息处理(MSMQ) 二第8张        MessageQueue myQueue = (MessageQueue)source;
 6ASP.NET中进行消息处理(MSMQ) 二第8张        //完成指定的异步接收操作
 7ASP.NET中进行消息处理(MSMQ) 二第8张        Message message = myQueue.EndReceive(asyncResult.AsyncResult);
 8ASP.NET中进行消息处理(MSMQ) 二第8张        signal.Set();
 9ASP.NET中进行消息处理(MSMQ) 二第8张        Book book = message.Body as Book;
10ASP.NET中进行消息处理(MSMQ) 二第8张        Console.WriteLine("图书编号:{0}--图书名称:{1}--图书作者:{2}--图书定价:{3}",
11ASP.NET中进行消息处理(MSMQ) 二第8张            book.BookId.ToString(),
12ASP.NET中进行消息处理(MSMQ) 二第8张            book.BookName,
13ASP.NET中进行消息处理(MSMQ) 二第8张            book.BookAuthor,
14ASP.NET中进行消息处理(MSMQ) 二第8张            book.BookPrice.ToString());
15ASP.NET中进行消息处理(MSMQ) 二第8张        myQueue.BeginReceive();
16ASP.NET中进行消息处理(MSMQ) 二第19张    }

17ASP.NET中进行消息处理(MSMQ) 二第8张    catch (MessageQueueException me)
18ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
19ASP.NET中进行消息处理(MSMQ) 二第8张        Console.WriteLine("异步接收出错,原因:" + me.Message);
20ASP.NET中进行消息处理(MSMQ) 二第8张
21ASP.NET中进行消息处理(MSMQ) 二第19张    }

22ASP.NET中进行消息处理(MSMQ) 二第28张}

四、MSMQ在邮件发送程序中的应用
     在邮件程序的应用中,实现发送邮件的方法有很多种,很多朋友都比较喜欢邮件发送组件(如:JMail),在.NET Framework里也给我们提供了发送邮件的类StmpClient,位于System.Net下。我想很多朋友都曾用到过此类,如果说是在一个小型的邮件应用里,完全没有使用MSMQ的必要,因为数据量不大,直接处理就OK,这里我以邮件程序来说只是出于对MSMQ应用的介绍。说实在的,我也不知道怎么才能把这个东东给介绍清楚,先看看一张图吧!
                         ASP.NET中进行消息处理(MSMQ) 二第252张
      现在的需求是这样的,有一个邮件发送客户端(SendMail.aspx,界面效果如上图所示)和一个邮件发送管理的服务端(MailServer.aspx),当在SendMail.aspx里发送邮件的时候,我们不直接将其发到目标地址去,而是将其发送到消息队列,然后由MailServer.aspx来负责从消息队列里读取出邮件信息在将其发送到目标地址。其实SendMail.aspx的职责就是完成把邮件信息发送到消息队列,示意性代码如下:
 1ASP.NET中进行消息处理(MSMQ) 二第1张protected void btnSendMail_Click(object sender, EventArgs e)
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张    //取出数据存入MailInfo对象
 4ASP.NET中进行消息处理(MSMQ) 二第8张    MailInfo info = new MailInfo();
 5ASP.NET中进行消息处理(MSMQ) 二第8张    info.Title = tbTitle.Text;
 6ASP.NET中进行消息处理(MSMQ) 二第8张    info.Content = tbContent.Text;
 7ASP.NET中进行消息处理(MSMQ) 二第8张    info.StmpServer = tbSmtpServer.Text;
 8ASP.NET中进行消息处理(MSMQ) 二第8张    info.Sender = tbSender.Text;
 9ASP.NET中进行消息处理(MSMQ) 二第8张    info.SenderPwd = tbSenderPwd.Text;
10ASP.NET中进行消息处理(MSMQ) 二第8张    info.ReceiveAddress = tbReceive.Text;
11ASP.NET中进行消息处理(MSMQ) 二第8张
12ASP.NET中进行消息处理(MSMQ) 二第8张    if (info != null)
13ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
14ASP.NET中进行消息处理(MSMQ) 二第8张        CreateQueue();
15ASP.NET中进行消息处理(MSMQ) 二第8张        SendMessage(info);
16ASP.NET中进行消息处理(MSMQ) 二第19张    }

17ASP.NET中进行消息处理(MSMQ) 二第28张}
     CreateQueue和SendMessage这两个方法完成消息队列的创建和发送信息到队列,MailInfo类封装的是邮件的详细信息(既邮件的属性),详细定义如下: 
ASP.NET中进行消息处理(MSMQ) 二第274张ASP.NET中进行消息处理(MSMQ) 二第275张封装了邮件的属性
 1ASP.NET中进行消息处理(MSMQ) 二第1张public class MailInfo
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张    public MailInfo()
 4ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
 5ASP.NET中进行消息处理(MSMQ) 二第8张       
 6ASP.NET中进行消息处理(MSMQ) 二第19张    }

 7ASP.NET中进行消息处理(MSMQ) 二第8张
 8ASP.NET中进行消息处理(MSMQ) 二第8张    private string _Title;
 9ASP.NET中进行消息处理(MSMQ) 二第8张    public string Title
10ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
11ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _Title; }
12ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _Title = value; }
13ASP.NET中进行消息处理(MSMQ) 二第19张    }

14ASP.NET中进行消息处理(MSMQ) 二第8张
15ASP.NET中进行消息处理(MSMQ) 二第8张    private string _Content;
16ASP.NET中进行消息处理(MSMQ) 二第8张
17ASP.NET中进行消息处理(MSMQ) 二第8张    public string Content
18ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
19ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _Content; }
20ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _Content = value; }
21ASP.NET中进行消息处理(MSMQ) 二第19张    }

22ASP.NET中进行消息处理(MSMQ) 二第8张    private string _Sender;
23ASP.NET中进行消息处理(MSMQ) 二第8张
24ASP.NET中进行消息处理(MSMQ) 二第8张    public string Sender
25ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
26ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _Sender; }
27ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _Sender = value; }
28ASP.NET中进行消息处理(MSMQ) 二第19张    }

29ASP.NET中进行消息处理(MSMQ) 二第8张    private string _SenderPwd;
30ASP.NET中进行消息处理(MSMQ) 二第8张
31ASP.NET中进行消息处理(MSMQ) 二第8张    public string SenderPwd
32ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
33ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _SenderPwd; }
34ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _SenderPwd = value; }
35ASP.NET中进行消息处理(MSMQ) 二第19张    }

36ASP.NET中进行消息处理(MSMQ) 二第8张    private string _StmpServer;
37ASP.NET中进行消息处理(MSMQ) 二第8张
38ASP.NET中进行消息处理(MSMQ) 二第8张    public string StmpServer
39ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
40ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _StmpServer; }
41ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _StmpServer = value; }
42ASP.NET中进行消息处理(MSMQ) 二第19张    }

43ASP.NET中进行消息处理(MSMQ) 二第8张    private string _ReceiveAddress;
44ASP.NET中进行消息处理(MSMQ) 二第8张
45ASP.NET中进行消息处理(MSMQ) 二第8张    public string ReceiveAddress
46ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
47ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        get ASP.NET中进行消息处理(MSMQ) 二第7张return _ReceiveAddress; }
48ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        set ASP.NET中进行消息处理(MSMQ) 二第7张{ _ReceiveAddress = value; }
49ASP.NET中进行消息处理(MSMQ) 二第19张    }

50ASP.NET中进行消息处理(MSMQ) 二第28张}

      转到邮件管理端(MailServer.aspx),他负责从消息队列里读取出邮件信息并把此邮件发送到目标地址去。其实现很简单,说直接点他也就是完成了两项操作(从队列读消息、将消息发送到目的邮箱),从队列读取消息的代码如下:
 1ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张/**//// <summary>
 2ASP.NET中进行消息处理(MSMQ) 二第8张/// 连接消息队列并从队列中接收消息
 3ASP.NET中进行消息处理(MSMQ) 二第28张/// </summary>

 4ASP.NET中进行消息处理(MSMQ) 二第1张private MailInfo ReceiveMessage()
 5ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 6ASP.NET中进行消息处理(MSMQ) 二第8张    MailInfo info = null;
 7ASP.NET中进行消息处理(MSMQ) 二第8张    //连接到本地队列
 8ASP.NET中进行消息处理(MSMQ) 二第8张    MessageQueue myQueue = new MessageQueue(".\\private$\\myMailQueue");
 9ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    myQueue.Formatter = new XmlMessageFormatter(new Type[] ASP.NET中进行消息处理(MSMQ) 二第7张typeof(MailInfo) });
10ASP.NET中进行消息处理(MSMQ) 二第8张    try
11ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
12ASP.NET中进行消息处理(MSMQ) 二第8张        if (myQueue.Transactional)
13ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        ASP.NET中进行消息处理(MSMQ) 二第7张{
14ASP.NET中进行消息处理(MSMQ) 二第8张            MessageQueueTransaction myTransaction = new MessageQueueTransaction();
15ASP.NET中进行消息处理(MSMQ) 二第8张            //启动事务
16ASP.NET中进行消息处理(MSMQ) 二第8张            myTransaction.Begin();
17ASP.NET中进行消息处理(MSMQ) 二第8张            //从队列中接收消息
18ASP.NET中进行消息处理(MSMQ) 二第8张            Message myMessage = myQueue.Receive(myTransaction);
19ASP.NET中进行消息处理(MSMQ) 二第8张            info = myMessage.Body as MailInfo; //获取消息的内容
20ASP.NET中进行消息处理(MSMQ) 二第8张            myTransaction.Commit();
21ASP.NET中进行消息处理(MSMQ) 二第8张            return info;
22ASP.NET中进行消息处理(MSMQ) 二第19张        }

23ASP.NET中进行消息处理(MSMQ) 二第8张
24ASP.NET中进行消息处理(MSMQ) 二第19张    }

25ASP.NET中进行消息处理(MSMQ) 二第8张    catch (MessageQueueException e)
26ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
27ASP.NET中进行消息处理(MSMQ) 二第8张        this.tdError.InnerText = e.Message;
28ASP.NET中进行消息处理(MSMQ) 二第19张    }

29ASP.NET中进行消息处理(MSMQ) 二第8张    return info;
30ASP.NET中进行消息处理(MSMQ) 二第28张}

      该方法(ReceiveMessage)返回的是从队列里读取到的邮件信息,本示例中只是做了读一条信息的实现,如果要把队列里的全部信息读出并发送到目的邮箱,可以参考我前面所介绍的相关知识点来实现。得到了邮件的详细信息,我们就可以使用相应的技术将这信息发送到目标邮箱去,本示例中我采用的是.NET Framework里提供的SmtpClient类来完成的邮件发送,关于SmtpClient类的使用网上有相当丰富的资料介绍,这里我就不做详细的说明,核心代码如下:
 1ASP.NET中进行消息处理(MSMQ) 二第1张protected void Button2_Click(object sender, EventArgs e)
 2ASP.NET中进行消息处理(MSMQ) 二第5张ASP.NET中进行消息处理(MSMQ) 二第6张ASP.NET中进行消息处理(MSMQ) 二第7张{
 3ASP.NET中进行消息处理(MSMQ) 二第8张    if (info != null)
 4ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张    ASP.NET中进行消息处理(MSMQ) 二第7张{
 5ASP.NET中进行消息处理(MSMQ) 二第8张        SmtpClient client = new SmtpClient();
 6ASP.NET中进行消息处理(MSMQ) 二第8张        client.Host = info.StmpServer;
 7ASP.NET中进行消息处理(MSMQ) 二第8张        client.UseDefaultCredentials = false;
 8ASP.NET中进行消息处理(MSMQ) 二第8张        client.Credentials = new NetworkCredential(info.Sender, info.SenderPwd);
 9ASP.NET中进行消息处理(MSMQ) 二第8张        client.DeliveryMethod = SmtpDeliveryMethod.Network;
10ASP.NET中进行消息处理(MSMQ) 二第8张
11ASP.NET中进行消息处理(MSMQ) 二第8张        MailMessage message = new MailMessage(info.Sender, info.ReceiveAddress);
12ASP.NET中进行消息处理(MSMQ) 二第8张        message.Subject = info.Title;
13ASP.NET中进行消息处理(MSMQ) 二第8张        message.Body = info.Content;
14ASP.NET中进行消息处理(MSMQ) 二第8张        message.BodyEncoding = Encoding.UTF8;
15ASP.NET中进行消息处理(MSMQ) 二第8张        message.IsBodyHtml = true;
16ASP.NET中进行消息处理(MSMQ) 二第8张
17ASP.NET中进行消息处理(MSMQ) 二第8张        try
18ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        ASP.NET中进行消息处理(MSMQ) 二第7张{
19ASP.NET中进行消息处理(MSMQ) 二第8张            //发送邮件到目标地址
20ASP.NET中进行消息处理(MSMQ) 二第8张            client.Send(message);
21ASP.NET中进行消息处理(MSMQ) 二第8张            this.tdSucces.InnerText = "邮件已成功发送到目标地址:" + info.ReceiveAddress;
22ASP.NET中进行消息处理(MSMQ) 二第19张        }

23ASP.NET中进行消息处理(MSMQ) 二第8张        catch (Exception ex)
24ASP.NET中进行消息处理(MSMQ) 二第15张ASP.NET中进行消息处理(MSMQ) 二第16张        ASP.NET中进行消息处理(MSMQ) 二第7张{
25ASP.NET中进行消息处理(MSMQ) 二第8张            this.tdError.InnerText = "发送失败,失败原因:" + ex.Message;
26ASP.NET中进行消息处理(MSMQ) 二第19张        }

27ASP.NET中进行消息处理(MSMQ) 二第19张    }

28ASP.NET中进行消息处理(MSMQ) 二第28张}

运行后的效果图如下:
                          ASP.NET中进行消息处理(MSMQ) 二第443张
      本文中的所有示例程序全部通过调试,能力有限,文中所介绍的不是很清楚,详细可直接下载源代码了解。本代码包里也包含有第一篇文章里的全部示例程序代码。
点击连接下载示例程序代码:示例程序代码下载

相关文章连接:
ASP.NET中进行消息处理(MSMQ) 一
ASP.NET中进行消息处理(MSMQ) 三

免责声明:文章转载自《ASP.NET中进行消息处理(MSMQ) 二》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇支付宝付款页面调整屏幕亮度win10下检查nvidia显卡支持的cuda版本下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SAP-Function

[转]sap函数大全 ********SAP中常用函数 函数名 描述SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的LINES中的行按照TDFORMAT=“*”重新组织VIEW_MAINTENANCE_CALL 维护表视图 函数名 描述DY_GET_FOCUS 获得屏幕焦点D...

网页实时聊天之PHP实现websocket

前言 websocket 作为 HTML5 里一个新的特性一直很受人关注,因为它真的非常酷,打破了 http “请求-响应”的常规思维,实现了服务器向客户端主动推送消息,本文介绍如何使用 PHP 和 JS 应用 websocket 实现一个网页实时聊天室; 以前写过一篇文章讲述如何使用ajax长轮询实现网页实时聊天,见链接: 网页实时聊天之js和jQuer...

wifi的几种工作模式

WIFI配置具体的模式主要有以下这几种:STA模式、AccessPoint模式、Monitor模式、Ad-hoc(IBSS)模式、WDS模式、Mesh模式。 第一种:STA模式 任何一种无线网卡都可以运行在此模式下,这种模式也可以称为默认模式。在此模式下,无线网卡发送连接与认证消息给热点,热点接收到后完成认证后,发回成功认证消息,此网卡接入无线网络。这种模...

VC Delphi WM_COPYDATA 消息

Delphi端发消息,VC接收消息参见: VC Delphi WM_COPYDATA 消息 本节是VC发消息,DELPHI端接收,VC字符集分为“Unicode”和”多字节“。 VC---->Unicode发送端代码: CString strSend = "要发送的信息"; strSend.ReleaseBuffer(); CWnd *pWnd =...

c++消息队列的实现

#ifndef NET_FRAME_CONCURRENT_QUEUE_H #define NET_FRAME_CONCURRENT_QUEUE_H #include <queue> #include <mutex> #include <condition_variable> template<cla...

c语言运算符

1.运算符概述 运算符是一种编译器执行特定的数学或逻辑操作的符号。C语言提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 其他运算符 2.算术运算符 算术运算符分为单目运算符和双目运算符,单目运算符表示只需要一个操作数,双目运算符需要两个操作数。 2.1 双目算术运算符 1)+ :加法,把两个操作数相加...