日期:2014-05-18 浏览次数:21034 次
以前在给学生讲解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