WPF消息隊列示例——結合項目經驗


  標題是有些奇怪,WPF消息隊列,消息隊列的使用和WPF或者WinForm有關系嗎?哦,沒有,當然沒有。只是我沒有用過WPF,因此打算用WPF寫這個DEMO。后半年的項目和微軟消息隊列練習非常緊密,整個項目的數據處理都是采用消息隊列傳輸的。在做項目總結之前,打算回顧一下消息隊列簡單的使用,具體項目中的應用下一篇在寫。

一、消息隊列的簡介

首先消息隊列是要安裝的,如果不了解,請度娘或谷哥之。MSMQ采用異步傳輸,可傳輸如文本、聲音、圖象等等。簡單說一下我對消息隊列的理解吧,就像開奧運會,站了很多隊伍(美國隊、中國隊),這個就類似於隊列;而中國隊中具體的張三李四王五,就類似於隊列中的消息。消息是可以獨立存在,但是它在發送的時候,必須依附於某個隊列。

其次,安裝完消息隊列之后,可以看到“傳出隊列”和“專用隊列”。傳出隊列顯示了,將要往外傳輸的消息的狀態;專用隊列,顯示了已經接受的消息隊列的狀態。

如上圖,左邊的Client端產生了數據,數據以消息隊列的方式發送出去。如果網絡正常聯通,則右邊的專用隊列會立刻接收到消息,消息會不斷的累積在專用隊列中。Server端接受處理消息之后,專用隊列中的消息就會相應的減少。從上圖及分析可以看出來,MSMQ是比較適合做分布式系統處理的。

二、一個簡單的WPF示例

a、新建一個WPF的工程,拖拽控件如下圖:

b、然后新增兩個文件“Book.cs”和“MsgQueue.cs”。前者主要是定義了含有四個四段的book類;后者主要包含了三個方法:創建新隊列CreateQueue()、發送消息SendMess()、接受消息ReveiceMess()。

具體代碼如下:

Book:

View Code
*
 * to define Book class,five property
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MSMQDemo
{
    public class Book
    {
        private int _BookId;
        public int BookId
        {
            get { return _BookId; }
            set { _BookId = value; }
        }

        private string _BookName;
        public string BookName
        {
            get { return _BookName; }
            set { _BookName = value; }
        }

        private string _BookAuthor;
        public string BookAuthor
        {
            get { return _BookAuthor; }
            set { _BookAuthor = value; }
        }

        private double _BookPrice;
        public double BookPrice
        {
            get { return _BookPrice; }
            set { _BookPrice = value; }
        }

    }
}

 

MsgQueue:

View Code
/*
 * MsgQueue:包含了創建、發送、接收三個隊列方法
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Messaging;
using System.Windows.Forms;

namespace MSMQDemo
{
    /// <summary>
    /// MsgQueue類,主要用於構造消息隊列
    /// </summary>
    public class MsgQueue
    {
        /// <summary>
        /// 創建消息隊列
        /// </summary>
        /// <param name="quePath"></param>
        public static void CreateQueue(string quePath)
        {
            try
            {
                if (!MessageQueue.Exists(quePath))
                {
                    MessageQueue.Create(@".\private$\myQueue");
                    MessageBox.Show("創建隊列成功!");
                }
                else
                {
                    MessageBox.Show(quePath + "隊列已創建,請勿重復創建!");
                }
            }
            catch (MessageQueueException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 鏈接並且發送消息隊列
        /// </summary>
        /// <param name="book"></param>
        public static bool SendMess(Book book)
        {
            bool flag = false;

            try
            {
                MessageQueue myQueue = new MessageQueue(@".\private$\myQueue");
                System.Messaging.Message message = new System.Messaging.Message();
                message.Body = book;
                message.Formatter = new XmlMessageFormatter(new Type[] { typeof(Book) });
                myQueue.Send(message);
                flag = true;
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show(ex.Message);
            }
            return flag;
        }

        /// <summary>
        /// 接收消息隊列
        /// </summary>
        public static string ReveiceMess()
        {
            MessageQueue myQueue = new MessageQueue(@".\private$\myQueue");
            myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Book) });

            try
            {
                System.Messaging.Message mess = myQueue.Receive();
                Book book = (Book)mess.Body;
                return string.Format("編號:{0},書名:{1},作者:{2},定價:{3}", book.BookId, book.BookName, book.BookAuthor, book.BookPrice);

            }
            catch (MessageQueueException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (InvalidCastException ex)
            {
                MessageBox.Show(ex.Message);
            }
            return "";
        }
    }
}

 

c、在WPF中的調用:

由於MsgQueue中的方法都是靜態的,因此在WPF后來可以直接進行調用。

代碼如下:

View Code
 /// <summary>
        /// 創建消息隊列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            MsgQueue.CreateQueue(@".\private$\"+textBox1.Text.Trim().ToString());
        }

        /// <summary>
        /// 發送隊列
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, RoutedEventArgs e)
        {
            Book book = new Book();
            book.BookId = int.Parse(textBox2.Text.ToString());
            book.BookName = textBox3.Text;
            book.BookAuthor = textBox4.Text;
            book.BookPrice = double.Parse(textBox5.Text.ToString());
            if (MsgQueue.SendMess(book))
            {
                MessageBox.Show("成功發送消息到隊列");
            }
        }

        private void ReveiceBtn_Click(object sender, RoutedEventArgs e)
        {
            this.textBox6.Text = MsgQueue.ReveiceMess();
        }

 最終演示效果:

三、擴展及代碼下載

a、三種消息發送的格式

.NET消息隊列提供了如下的格式程序:XmlMessageFormatter  ,BinaryMessageFormatter   ,ActiveXMessageFormatter 。上面的例子中,使用的是XmlMessageFormatter 。  

類型 特性
XmlMessageFormatter  這是默認的格式化程序,前面的例子都是使用它的,從這個名稱我們就可以聯想到,它是會將自定義的類型串行化為一個XML表示,這個格式化程序很慢,並且會創建相對較多的消息。然而,這些消息可以被運行在不同平台下的應用程序共享和理解。
BinaryMessageFormatter   這個格式化應用程序會把自定義類型串行化為一個專有的二進制的格式。他比上面一種的速度要快得多,而且生成的消息很緊湊。然而只有運行在.NET中的接收者才可以容易地解析這個消息的內容。
ActiveXMessageFormatter   ActiveXMessageFormatter   和BinaryMessageFormatter一樣,他會把自定義的類型串行化為專用的二進制格式。這個格式也就是MSMQ的COM組件使用的格式。這些傳統的COM組件為COM語言(比如Visual Basic 6)提供了基於MSMQ的功能。因此,您可以在用Visual Basic 6編寫的MSMQ應用程序中使用這個格式化程序來發送消息或接收消息。

b、代碼下載,點擊這里

c、在分布式系統中的使用

微軟petshop寵物商店用到了消息隊列,有興趣的也可以自行下載看看。

本篇參考了,http://www.cnblogs.com/beniao/archive/2008/06/26/1229934.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM