适用于WinForm的一个定时器类

尽管.Net已经提供了3个Timer,我仍然要自己利用BackgroundWorker组件封装这么一个定时器来使用。

主要原因是System.Windows.Forms以及System.Threading.Timer的Timer同时运行多个的时候会产生令人发狂的错乱,停止其中一个Timer的时候,可能会引发其他Timer注册的事件,对此类灵异事件,查遍互联网后只在MSDN发现了这么一段说明:

由于所有 Timer 组件都在主应用程序线程上操作,所以在 Windows 窗体应用程序中的任意 Timer 上调用 Stop 都可以导致来自应用程序中其他 Timer 组件的消息被立即处理。如果有两个 Timer 组件,分别设置为 700 毫秒和 500 毫秒,并且从第一个 Timer 调用 Stop,则应用程序可能首先接收第二个组件的事件回调。如果这证明有问题,请考虑转为使用 System.Threading 命名空间中的 Timer 类。

而System.Threading.Timer的Timer又让我感到非常晦涩难用,所以就造了一个山寨版的定时器:

     public   class  定时器
ExpandedBlockStart.gifContractedBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 创建一个定时器对象。
        
/// </summary>
        
/// <param name="定时">指示定时时间,以毫秒为单位。</param>
        
/// <param name="间歇时间">指示定时之中的间歇时间,用于检查是否取消执行。</param>

        public 定时器(int 定时, int 间歇时间)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.定时 = 定时;
            
if (间歇时间 < 10throw new Exception("间歇时间不得小于10毫秒!");
            
this.间歇时间 = 间歇时间;
        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 指示定时时间,以毫秒为单位。
        
/// </summary>

        public int 定时
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _定时;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _定时 
= value;
            }

        }

        
private int _定时;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 指示定时之中的间歇时间,用于检查是否取消执行。
        
/// </summary>

        public int 间歇时间
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _间歇时间;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _间歇时间 
= value;
            }

        }

        
private int _间歇时间;
        
private BackgroundWorker 后台处理进程
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _后台处理进程;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _后台处理进程 
= value;
            }

        }

        
private BackgroundWorker _后台处理进程;
        
private object 附件
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _附件;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _附件 
= value;
            }

        }

        
private object _附件;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 指示定时器是否处于运行状态
        
/// </summary>

        public bool 执行中
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _执行中;
            }

        }

        
private bool _执行中;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 启动定时器,如果定时器已经启动,则引发异常。
        
/// </summary>
        
/// <param name="附件">在定时完成时可能被使用到的传递对象。</param>

        public void 执行(object 附件)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (执行中) throw new Exception("定时器已启动!");
            _执行中 
= true;
            
this.附件 = 附件;
            后台处理进程 
= new BackgroundWorker();
            后台处理进程.WorkerSupportsCancellation 
= true;
            后台处理进程.DoWork 
+= new DoWorkEventHandler(b_DoWork);
            后台处理进程.RunWorkerCompleted 
+= new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
            后台处理进程.RunWorkerAsync(
this);
        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 请求中止执行,如果定时器尚未启动,则引发异常。
        
/// </summary>

        public void 中止(bool 取消触发完毕事件)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (!执行中) throw new Exception("定时器尚未启动!");
            
this.取消触发完毕事件 = 取消触发完毕事件;
            后台处理进程.CancelAsync();
        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 达到定时事件代理
        
/// </summary>

        public delegate void 执行完毕代理(定时器 sender, object 附件, bool 是否为用户取消);
        
private bool 取消触发完毕事件
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _取消触发完毕事件;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _取消触发完毕事件 
= value;
            }

        }

        
private bool _取消触发完毕事件;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// 达到定时事件
        
/// </summary>

        public event 执行完毕代理 执行完毕事件;

        
void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (e.Error != nullthrow e.Error;
            
if (!取消触发完毕事件&&执行完毕事件 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                var o 
= e.Result as 定时器;
                执行完毕事件(o, o.附件, e.Cancelled);
            }

            _执行中 
= false;
            后台处理进程.Dispose();
        }


        
void b_DoWork(object sender, DoWorkEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            var o 
= e.Argument as 定时器;
            e.Result 
= o;
            
int x = 0;
            
while (true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (x >= o.定时 || (sender as BackgroundWorker).CancellationPending) break;
                Thread.Sleep(o.间歇时间);
                x 
+= o.间歇时间;
            }

        }

    }

 

使用起来很简单,“new”了之后“执行()”就可以了。

使用了WinForm的BackgroundWorker组件,所以不晓得ASP.Net能不能用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Winform中有两种常用的定时器,分别是System.Windows.Forms.Timer和System.Timers.Timer。\[1\]System.Windows.Forms.Timer是作为Winform一个组件,使用简单方便。你可以直接将该组件拖放到Winform上,然后设置定时器的间隔时间,通过事件处理函数来执行定时任务。但是需要注意的是,System.Windows.Forms.Timer的执行频率并不是完全准确的,有时候会有一定的误差。\[3\] 另一种定时器是System.Timers.Timer,它需要通过编写代码来实现。你需要在代码中创建一个System.Timers.Timer对象,并设置定时器的间隔时间。然后通过事件处理函数来执行定时任务。相比于System.Windows.Forms.Timer,System.Timers.Timer的执行频率更加准确,完全按照设置的时间频率执行。\[2\] 下面是一个使用System.Timers.Timer的例子: ```csharp using System; using System.Timers; namespace WindowsFormsApplication1 { public partial class Form2 : Form { private int cnt = 0; private System.Timers.Timer myTimer; public Form2() { InitializeComponent(); } private void Form2_Load(object sender, EventArgs e) { // 创建定时器,并设置执行频率时间 this.myTimer = new System.Timers.Timer(1000); // 设置定时器执行的任务 this.myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed); this.myTimer.AutoReset = true; this.myTimer.Enabled = true; this.myTimer.Start(); } /** * 定时器执行的任务 */ private void myTimer_Elapsed(object sender, ElapsedEventArgs e) { cnt++; Console.WriteLine("myTimer-- " + cnt); } } } ``` 总结来说,如果你需要一个简单方便的定时器,可以使用System.Windows.Forms.Timer。但如果你需要一个准确的定时器,可以选择使用System.Timers.Timer。 #### 引用[.reference_title] - *1* *2* *3* [winform中对定时器的使用](https://blog.csdn.net/iteye_10824/article/details/82602293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值