日期:2014-05-18  浏览次数:20930 次

COM+队列的C#实现

以前在给学生讲解COM+队列服务的时候,曾举了个例子:
比如你想给张三一记耳光,但张三不在眼前,明天才会来,可明天你又不在,怎么也碰不到张三,怎么办呢?这时候你可以使用COM+的队列服务,把你打耳光的动作用Recorder录入COM+队列中,等张三回来了,队列服务中的Player才真正播放这个动作,把这记耳光赏给张三。
例子比较粗俗,但想起张三那个倒霉样就想笑,科技发展那么快,说不准哪天就有这样的技术出现了。
在软件运行过程中,很多操作不需要进行同步调用,也不需要进行异步通知,这时候我想起来队列服务,忽然发现用C#的反射技术很容易实现,于是用C#实现了一个简单的队列,由Recorder、Listener、Player组成。

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;

namespace ObjectQueue
{

    #region Interface

    /// <summary>
    /// 记录器接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface iRecorder<T>
    {
        /// <summary>
        /// 已记录条目总数
        /// </summary>
        long Total { get; }
        void Record(T MethodInfo);
        T GetNextItem();
    }

    /// <summary>
    /// 监听器接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface iListener<T>
    {
        void Start(int interval);
    }

    /// <summary>
    /// 播放器接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface iPlayer<T>
    {
        /// <summary>
        /// 已播放条目总数
        /// </summary>
        long Total { get; }
        void Play(T t);
    }
    #endregion

    #region Implementation

    public class cMethodInfo
    {

        public Object Obj { get; set; }
        public string MethodName { get; set; }
        public Object[] Params { get; set; }

        public cMethodInfo(object obj, string methodName, object[] paramArray)
        {
            Obj = obj;
            MethodName = methodName;
            Params = paramArray;
        }
    }

    public class cRecorder : iRecorder<cMethodInfo>
    {
        private long total;
        private Queue<cMethodInfo> MethodInfoQue = new Queue<cMethodInfo>();
        #region iRecorder<cMethodInfo> 成员
        public void Record(cMethodInfo MethodInfo)
        {
            MethodInfoQue.Enqueue(MethodInfo);
            Interlocked.Increment(ref total);
        }
        public cMethodInfo GetNextItem()
        {
            if (MethodInfoQue.Count > 0)
            {
                return MethodInfoQue.Dequeue();
            }
            else
            {
                return null;
            }
        }

        public long Total
        {
            get
            {
                return total;
            }
        }

        #endregion
    }

    public class cListener : iListener<cMethodInfo>
    {
        private Timer Timer1;
        private iRecorder<cMethodInfo> mRecorder;
        private iPlayer<cMethodInfo> mPlayer;
        public cListener(iRecorder<cMethodInfo> Recorder, iPlayer<cMethodInfo> Player)
        {
            mRecorder = Recorder;
            mPlayer = Player;
        }

        /// <summary>
        /// cPlayer
        /// </summary>
        /// <param name="playInterval">播放频率,单位 毫秒,最小值为100</param>
        public void Start(int interval)
        {
            if (interval < 100) interval = 100;
            Timer1 = new Timer(CheckNewItem,
                "", 1000, interval);
        }
        private void CheckNewItem(object obj)
        {
            cMethodInfo item = mRecorder.GetNextItem();
            if (item != null)
            {
                mPlayer.Play(item);
            }
        }
    }

    /// <summary>
    /// 独立线程中执行
    /// </summary>
    public class cPlayer : iPlayer<cMethodInfo>
    {

        private long total;
        #region iPlayer<cMethodInfo> 成员
        public void Play(cMethodInfo Method)
        {
            Type myType = Method.Obj.GetType();
            MethodInfo display