petshop4.0学習ノートのメッセージキュー(MSMQ)


今日になって、私たちが毎日使っているWindowシステムには、メッセージキューというプログラミングコンポーネントがあります.大きなデータ量の交換の場合の性能問題、特にBSシステムのデータベース性能を解決することができる.また、その非同期処理方式はプログラマーに最大の便利さと最高のユーザー体験を与えることができる.
 
      1.まずメッセージキューが必要なサーバにMSMQをインストールします.私のシステムはwin 2003+iis 6なので、このインストールオプションは削除プログラム->windowsコンポーネント->アプリケーションサーバを追加します.デフォルトではインストールされていません.手動で選択する必要があります.
      2.メッセージキューの格納パスを確立する.これはwindowsのコンピュータ管理に追加することもできるし、プログラムに追加することもできる.プログラムに追加しました.
      3.はい.NetではSystemを参照する.Messaging;
     
     
using System;
using System.Collections.Generic;
using System.Messaging;

namespace MSMQ
{
    class Program
    {
        private const string path = @".\private$\ljz";
        private static MessageQueue queue = MessageQueue.Exists(path) ? new MessageQueue(path) : MessageQueue.Create(path, true);
        //private static List<string> list = new List<string>();

        public enum Level
        { 
            Low,
            Normal,
            High
        }

        static void Main(string[] args)
        {
            Send("   !", Level.Low);
            Send("   !", Level.Normal);
            Send("   !", Level.High);
            Console.WriteLine(Receive());
            Console.WriteLine(Receive());
            Console.WriteLine(Receive());
            Send("     !", Level.Normal);
            Send("     !", Level.High);
            Send("     !", Level.Low);
            ReceiveByAsyn();
            //foreach (string str in list)
            //{
            //    Console.WriteLine(str);
            //}
            Console.ReadKey();
        }

        public static void Send(string content, Level level)
        {
            System.Messaging.Message message = new System.Messaging.Message();
            message.Formatter = new System.Messaging.BinaryMessageFormatter();
            message.Body = content;
            switch (level)
            {
                case Level.Low:
                    message.Priority = MessagePriority.Low;
                    break;
                case Level.High:
                    message.Priority = MessagePriority.High;
                    break;
                default:
                    message.Priority = MessagePriority.Normal;
                    break;
            }
            //MessageQueueTransaction tran = new MessageQueueTransaction();
            //try
            //{
            //    tran.Begin();
            //    queue.Send(message);
            //    tran.Commit();
            //}
            //catch
            //{
            //    tran.Abort();
            //}
            queue.Send(message, MessageQueueTransactionType.Automatic);
        }

        public static string Receive()
        {
            System.Messaging.Message message = queue.Receive();
            message.Formatter = new System.Messaging.BinaryMessageFormatter();

            return message.Body.ToString();
        }

        public static void ReceiveByAsyn()
        {
            queue.ReceiveCompleted += new ReceiveCompletedEventHandler(queue_ReceiveCompleted);
            queue.BeginReceive();
        }

        private static void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
        {
            MessageQueue queueTmp = sender as MessageQueue;
            System.Messaging.Message mess = queueTmp.EndReceive(e.AsyncResult);
            mess.Formatter = new System.Messaging.BinaryMessageFormatter();
            Console.WriteLine(mess.Body.ToString());
            //list.Add(mess.Body.ToString());
            queueTmp.BeginReceive();
        }
    }
}

 
以下、上記のコードについていくつか説明します.
1.上のコードには例外処理はありませんが、このようなコードは必ず例外処理を加えなければなりません.
2.経路メッセージキューにはいくつかあり、他の人にアクセスできるものもあれば、共通キューのように、自分でアクセスできるものもあります.例えば、専用キューです.具体的な分類は、以下に示す参考文章を参照してください.いずれも使用できるわけではない.私のようなワークグループモードのパソコンは、専用のキューしか使えません.つまり、自分で自分にアクセスするしかありません.パスの書き方には違いがあります.
Public:  [MachineName]\[QueueName]
Private:  [MachineName]\Private$\[QueueName]


 
3.メッセージキューを使用するには、Systemという2つの重要なクラスがあります.Messaging.MessageとSystem.Messaging.MessageQueue.私がフルネームを挙げたのは、Netに同名のクラスがあるから、混同しないでください.以下のMessageQueueとMessageは特に上の2つのクラスを指す.
MessageQueueはメッセージキューオブジェクトで、SendとReceiveの2つの重要な方法があります.名前の通り、Sendはメッセージキューにメッセージを送信、Receiveはメッセージキューからメッセージを受信する.
Messageはメッセージオブジェクトです.2つの重要な属性Formatterは、コンテンツのシーケンス化フォーマットの属性であり、Bodyはコンテンツを格納する主体である.上の例では文字列を置いていますが、オブジェクトがシーケンス化されなければならないことを前提に、オブジェクトを置くこともできます.
 
以上より,メッセージキューのDemoを1つ書けるようになったが,まだ実用的ではない,以下ではその実用的な属性について述べる.
1.優先度実際のアプリケーションではメッセージに優先度がある、重要なメッセージが優先的に処理する必要があるメッセージがあるのは一般的であることは否めない.どのように体現しますか?MessageオブジェクトにはPriority属性があり、8つのレベルがあり、私は上記の例でその中の3つしか使用していません.優先度を設定ことで、重要なメッセージを優先的に処理することができる.
2.事務时には、データを転送する过程の中で、データの一致性を保证する必要があって、データベースの中でよく事务を使って、実はここにも事务があって、上の例の中で56-66行のコードは事务処理で、しかし书くのは比较的に面倒で、実は67行の书き方を采用して、システムに自分で保护することができます.
3.非同期処理MessageQueueオブジェクトのReceiveメソッドには、キューにデータがない場合、新しいデータが入るまでスレッドがロックされるという欠点がある.これは実はよくないです.より良い処理方法は、既存のスレッドに影響を与えることなく、新しいスレッドを開いて処理することである.はい.Netでは例の80と81行と書く、メッセージオブジェクトに依頼をロードし、処理コードを依頼内に置く.
 
コードの11行目、32-35行目、90行目は私が意図的に注掉したので、実は私が考えているのは非同期でメッセージを処理する时、したことはただデータを取り出すだけでいいべきで、まだ中で処理するべきではありません.別の場所でデータを処理するのです私は局所変数listを宣言して、道理で90行目のデータが取り出した後にこのlistに参加することができるべきで、しかし事実は取り出したデータが入れることができて、時にはだめです.これはマルチスレッドの問題だと思います.Netのデフォルトではスレッド間の相互内部呼び出しが禁止する.Listはメインスレッドの変数である、非同期を開いた後にサブスレッドに値を付与することは許されない.しかし、私が理解できないのは、なぜ时には成功することができるのかということです.私の理解が間違っているのかもしれません.もし誰かが私の困惑を見たら、私に教えてほしい.マルチスレッドについてはまだよく分かりません.(汗一つ~~~)
 
実は、個人的には、メッセージキューの応用範囲はまだ限られていると思っています.まず、彼はwindowシステムしかありません.Netで呼び出すと、ネットワーク帯域幅に対する要求が高い.だからローカルエリアネットワーク内で応用するのは比較的に良くて、interent上の応用、実はもっと良い解決策があります:.Netremotingとwebサービス
 
Demoダウンロード:
http://ljzforever.qupan.com/?folder=951925
 
 
参考資料:
ASP.NETにおけるメッセージ処理(MSMQ)一
http://dev.yesky.com/178/8196178.shtml
ASP.NETにおけるメッセージ処理(MSMQ)2
http://dev.yesky.com/229/8196229.shtml
 .Net+msmqクイックアクセスデータベース
http://developer.ccidnet.com/art/322/20030214/37984_1.html
メッセージキュー(Message Queue)の概要とその使用
http://www.cnblogs.com/rickie/archive/2004/11/16/64345.html
 
msmq 2つのネットワークドメイン間のメッセージ転送と受信テストの概要
http://www.cnblogs.com/billqi/archive/2005/12/29/307371.html
MSMQはASP.NETでの応用問題は?ありがとう!
http://topic.csdn.net/t/20020829/11/979610.html
 . Net環境におけるメッセージキュー(MSMQ)オブジェクトの応用
http://www.cnblogs.com/rickie/archive/2004/11/17/64712.aspx
.netのMSMQ非同期呼び出し
http://www.wangchao.net.cn/bbsdetail_37204.html
MSMQの使用
http://myxq.cnblogs.com/archive/2005/03/15/119150.aspx