技术开发 频道

C#多线程-不同线程间通过委托封送调用方法

【IT168技术文档】

    前两天做了一个自定义单件Timer,该Timer能够根据相应数据记录(Row)中的记录ID和设定分钟Minutes 做相应的事件调用,但是如果此事件处理程序在一Form中时则不能正确调用它,但是把82到93行的注释去掉就可以了。

    Timer大体定义如下:

using System; using System.Threading; using System.ComponentModel; using System.Windows.Forms; /************************************************************ * MyTimer.Timer能够根据同一Timer定时基准对不同的定时事件做定时。 * * MyTimer.Timer包含一Hashtable和Threading.Timer,每次Timer定时回调 * 遍历Hashtable并根据其中的TimerNode的定时周期值是否为零来判断是否调用 * 相应的TimerCome事件。 *************************************************************/ namespace MyTimer { /// <summary> /// 事件定时节点 /// </summary> internal class TimerNode { /// <summary> /// 构造函数 /// </summary> /// <param name="TimeCount">定时周期数</param> /// <param name="EvtID">事件ID</param> public TimerNode(long TimeCount,object EvtID) { this.mTimeCount=TimeCount; this.mEvtID=EvtID; } private long mTimeCount; private object mEvtID; public long TimeCount { get{return mTimeCount;} set{mTimeCount=value;} } public object EvtID { get{return mEvtID;} } } public class TimerEventArgs:EventArgs { private System.Collections.ArrayList mEvtIDs; public System.Collections.ArrayList EvtIDs { get{return mEvtIDs;} } /// <summary> /// 构造 /// </summary> /// <param name="EvtIDs">触发的事件ID列表</param> public TimerEventArgs(System.Collections.ArrayList EvtIDs):base() { this.mEvtIDs=EvtIDs; } } public delegate void TimerEventHandler(TimerEventArgs e); /// <summary> /// Timer 单件模式,不能实例化。 /// </summary> public class Timer { /// <summary> /// 有节点定时到事件 /// </summary> public static event TimerEventHandler TimeCome; /// <summary> /// 唤醒TimeCome事件。 /// </summary> /// <param name="e">此参数包含定时到事件列表</param> static void RaiseTimeCome(TimerEventArgs e) { if(TimeCome!=null) { // if(TimeCome.Target is System.ComponentModel.ISynchronizeInvoke) // { // System.ComponentModel.ISynchronizeInvoke aSynch=TimeCome.Target as System.ComponentModel.ISynchronizeInvoke; // if(aSynch.InvokeRequired) // { // object[] args=new object[1]{e}; // aSynch.BeginInvoke(TimeCome,args); // } // else // TimeCome(e); // } // else TimeCome(e); } } static readonly long mPeriod=1000*60;//定时间隔1分钟。 static System.Threading.Timer mTimer; static Timer() { mTimer=new System.Threading.Timer(new TimerCallback(TimeArrive),null,Timeout.Infinite,mPeriod); } /// <summary> /// 定时器开始运行 /// </summary> public static void Run() { mTimer.Change(0,mPeriod); } /// <summary> /// 定时器停止。 /// </summary> public static void Stop() { mTimer.Change(Timeout.Infinite,mPeriod); } /// <summary> /// 加入定时事件,如果此定时事件已存在则修改其定时周期。 /// </summary> /// <param name="EvtID">事件ID</param> /// <param name="TimeCount">周期数</param> public static void Add(object EvtID,long TimeCount) { if(mTimerNodes.ContainsKey(EvtID)) { ((TimerNode)mTimerNodes[EvtID]).TimeCount=TimeCount; } else mTimerNodes.Add(EvtID,new TimerNode(TimeCount,EvtID)); } /// <summary> /// 移除此定时事件 /// </summary> /// <param name="EvtID">事件ID</param> public static void Remove(object EvtID) { if(mTimerNodes.ContainsKey(EvtID)) mTimerNodes.Remove(EvtID); } /// <summary> /// 此函数是基准定时器mTimer的回调函数, /// 在此函数中将检查事件表,如期事件定时周期数已到则将其加入事件参数中 /// 并唤醒事件。 /// </summary> /// <param name="state"></param> static void TimeArrive(object state) { System.Collections.ArrayList EvtIDs=new System.Collections.ArrayList(); foreach(TimerNode aNode in mTimerNodes.Values) { aNode.TimeCount--; if(aNode.TimeCount<=0) { EvtIDs.Add(aNode.EvtID); } } if(EvtIDs.Count>0) { for(int i=0;i<EvtIDs.Count;i++) { mTimerNodes.Remove(EvtIDs[i]); } RaiseTimeCome(new TimerEventArgs(EvtIDs)); } } /// <summary> /// 事件表 /// </summary> static System.Collections.Hashtable mTimerNodes=new System.Collections.Hashtable(); } }


0
相关文章