MSMQ消息通知系统之消息队列多线程监视器

using System.Messaging;

using System;

using System.Threading;

using System.Transactions;

using System.Collections;

namespace MsmqDemo

{

    [Serializable]

    class MessageBase

    {

        /// <summary>

        /// 消息类型

        /// </summary>

        private string messagetype;

        public string MessageType

        {

            get { return messagetype; }

            set { messagetype = value; }

        }

        /// <summary>

        /// 消息内容

        /// </summary>

        private string messagebody;

        public string MessageBody

        {

            get { return messagebody; }

            set { messagebody = value; }

        }

    }

    class MsgRecorder:IDisposable

    {

        protected static readonly string path=@"FormatName:DIRECT=OS:.\Private$\MessageQueue";

        protected MessageQueueTransactionType type = MessageQueueTransactionType.Automatic;

        protected TimeSpan timeout;// = TimeSpan.FromSeconds(10d);

        protected MessageQueue queue;

        public MsgRecorder(int _timeout)

        {

            this.timeout = TimeSpan.FromSeconds(Convert.ToDouble(_timeout));

            queue = new MessageQueue(path);

            // Performance optimization since we don't need these features

            queue.DefaultPropertiesToSend.AttachSenderId = false;

            queue.DefaultPropertiesToSend.UseAuthentication = false;

            queue.DefaultPropertiesToSend.UseEncryption = false;

            queue.DefaultPropertiesToSend.AcknowledgeType = AcknowledgeTypes.None;

            queue.DefaultPropertiesToSend.UseJournalQueue = false;

 

        }

        public virtual Message Receive()

        {

            try

            {

                using (Message msg = queue.Receive(timeout, type))

                    return msg;

 

            }

            catch

            {

                throw;

            }

        }

 

        #region IDisposable 成员

 

        public void Dispose()

        {

            queue.Dispose();

        }

 

        #endregion

    }

    class Program

    {

        private static readonly int threadCount = 2;

        private static readonly int batchSize = 10;

        private static readonly int transactionTimeout = 10;

        private static readonly int queueTimeout = 10;

        private static int totalOrdersProcessed = 0;

 

        static void Main ()

        {

            Thread workticketThread;

            Thread[] threads = new Thread[threadCount];

            for (int i = 0; i < threadCount; i++)

            {

                workticketThread = new Thread(new ThreadStart(ProcessData));

                workticketThread.IsBackground = true;

                 //STA Thread 将创建并进入一个单线程单元。

                 //MTA Thread 将创建并进入一个多线程单元。

                 //Unknown 尚未设置ApartmentState 属性。

 

                workticketThread.SetApartmentState(ApartmentState.STA);

                workticketThread.Start();

                threads[i] = workticketThread;

            }

            Console.WriteLine("Processing started. Press Enter to stop.");

            Console.ReadLine();

            Console.WriteLine("Aborting Threads. Press wait...");

            //abort all threads

            foreach (Thread t in threads)

            {

                t.Abort();

            }

 

            Console.WriteLine("Process compeltely");

           

        }

        private static void ProcessData()

        {

            // the transaction timeout should be long enough to handle all of orders in the batch

            TimeSpan tsTimeout = TimeSpan.FromSeconds(Convert.ToDouble(transactionTimeout * batchSize));

            while (true)

            {

                TimeSpan datatimeStarting =new TimeSpan( DateTime.Now.Ticks);

                double elapsedTime = 0;

                int processedItems = 0;

                ArrayList queueOrders = new ArrayList();

                #region scope

                    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, tsTimeout))

                    {

                        using (MsgRecorder recorder = new MsgRecorder(queueTimeout))

                        {

                            for (int j = 0; j < batchSize; j++)

                            {

                                try

                                {

                                    if ((elapsedTime + queueTimeout + transactionTimeout) < tsTimeout.TotalSeconds)

                                    {

                                        //message list

                                        queueOrders.Add(recorder.Receive());

                                    }

                                    else

                                    {

                                        //timeout

                                        j = batchSize;   // exit loop

                                    }

                                    //update elapsed time

                                    elapsedTime = new TimeSpan(DateTime.Now.Ticks).TotalSeconds - datatimeStarting.TotalSeconds;

 

                                }

                                catch (TimeoutException)

                                {

                                    //exit loop because no more messages are waiting

                                    j = batchSize;

                                }

                                catch (Exception)

                                {

                                    j = batchSize;

                                    Console.WriteLine("已经没有数据,线程进入休眠~~~~~~~~~~~~~。。~");

                                    System.Threading.Thread.Sleep(60 * 1000);

                                }

 

                            }

                            //process the queued orders

                            for (int k = 0; k < queueOrders.Count; k++)

                            {

                                //process

                                Console.WriteLine("process one");

                                processedItems++;

                                totalOrdersProcessed++;

                            }

                            //batch complete or MSMQ receive timed out

                            scope.Complete();

                        }

 

                        Console.WriteLine("(Thread Id " + Thread.CurrentThread.ManagedThreadId + ") batch finished, " + processedItems + " items, in " + elapsedTime.ToString() + " seconds. Now:"+DateTime.Now.ToShortTimeString());

 

                    }

                    #endregion                   

            }

        }

 

    }

}

 

你可能感兴趣的:(消息队列)