尽管.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 定时器
    {
        /// <summary>
        /// 创建一个定时器对象。
        /// </summary>
        /// <param name="定时">指示定时时间,以毫秒为单位。</param>
        /// <param name="间歇时间">指示定时之中的间歇时间,用于检查是否取消执行。</param>
        public 定时器(int 定时, int 间歇时间)
        {
            this.定时 = 定时;
            if (间歇时间 < 10) throw new Exception("间歇时间不得小于10毫秒!");
            this.间歇时间 = 间歇时间;
        }
        /// <summary>
        /// 指示定时时间,以毫秒为单位。
        /// </summary>
        public int 定时
        {
            get
            {
                return _定时;
            }
            set
            {
                _定时 = value;
            }
        }
        private int _定时;
        /// <summary>
        /// 指示定时之中的间歇时间,用于检查是否取消执行。
        /// </summary>
        public int 间歇时间
        {
            get
            {
                return _间歇时间;
            }
            set
            {
                _间歇时间 = value;
            }
        }
        private int _间歇时间;
        private BackgroundWorker 后台处理进程
        {
            get
            {
                return _后台处理进程;
            }
            set
            {
                _后台处理进程 = value;
            }
        }
        private BackgroundWorker _后台处理进程;
        private object 附件
        {
            get
            {
                return _附件;
            }
            set
            {
                _附件 = value;
            }
        }
        private object _附件;
        /// <summary>
        /// 指示定时器是否处于运行状态
        /// </summary>
        public bool 执行中
        {
            get
            {
                return _执行中;
            }
        }
        private bool _执行中;
        /// <summary>
        /// 启动定时器,如果定时器已经启动,则引发异常。
        /// </summary>
        /// <param name="附件">在定时完成时可能被使用到的传递对象。</param>
        public void 执行(object 附件)
        {
            if (执行中) throw new Exception("定时器已启动!");
            _执行中 = true;
            this.附件 = 附件;
            后台处理进程 = new BackgroundWorker();
            后台处理进程.WorkerSupportsCancellation = true;
            后台处理进程.DoWork += new DoWorkEventHandler(b_DoWork);
            后台处理进程.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
            后台处理进程.RunWorkerAsync(this);
        }
        /// <summary>
        /// 请求中止执行,如果定时器尚未启动,则引发异常。
        /// </summary>
        public void 中止(bool 取消触发完毕事件)
        {
            if (!执行中) throw new Exception("定时器尚未启动!");
            this.取消触发完毕事件 = 取消触发完毕事件;
            后台处理进程.CancelAsync();
        }
        /// <summary>
        /// 达到定时事件代理
        /// </summary>
        public delegate void 执行完毕代理(定时器 sender, object 附件, bool 是否为用户取消);
        private bool 取消触发完毕事件
        {
            get
            {
                return _取消触发完毕事件;
            }
            set
            {
                _取消触发完毕事件 = value;
            }
        }
        private bool _取消触发完毕事件;
        /// <summary>
        /// 达到定时事件
        /// </summary>
        public event 执行完毕代理 执行完毕事件;

        void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null) throw e.Error;
            if (!取消触发完毕事件&&执行完毕事件 != null)
            {
                var o = e.Result as 定时器;
                执行完毕事件(o, o.附件, e.Cancelled);
            }
            _执行中 = false;
            后台处理进程.Dispose();
        }

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

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

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

本文转自斯克迪亚博客园博客,原文链接:http://www.cnblogs.com/SkyD/archive/2009/04/12/timer.html,如需转载请自行联系原作者

适用于WinForm的一个定时器类相关推荐

  1. python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?

    原标题:技术图文:如何利用 Python 做一个简单的定时器类? 背景 今天在B站上看有关 Python 最火的一个教学视频 -- "零基础入门学习 Python",这也是我们 P ...

  2. 关于C#中timer类 在C#里关于定时器类就有3个

    ·关于C#中timer类  在C#里关于定时器类就有3个   1.定义在System.Windows.Forms里   2.定义在System.Threading.Timer类里   3.定义在Sys ...

  3. java定时任务中使用多线程_java项目中如何利用多线程实现一个定时器任务

    java项目中如何利用多线程实现一个定时器任务 发布时间:2020-11-10 16:04:03 来源:亿速云 阅读:86 作者:Leah 今天就跟大家聊聊有关java项目中如何利用多线程实现一个定时 ...

  4. java定时器每一分钟执行一次_2行代码搞定一个定时器

    如何使用? 用法 1.需要定时执行的方法上加上@Scheduled注解,这个注解中可以指定定时执行的规则,稍后详细介绍. 2.Spring容器中使用@EnableScheduling开启定时任务的执行 ...

  5. Android自定义控件学习(四)------创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的设计,自定义视图应该: 符合And ...

  6. android自定义View学习(一)----创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的班级,自定义视图应该: 符合And ...

  7. Java如何简单实现一个定时器

    什么是定时器? 它就像是一个闹钟一样,提醒你在一定时间之后该去做什么~~ 前面在线程池的时候提到过两种可以执行延迟任务的方法 创建一个单线程可以执行延迟任务的线程池,Executors.newSing ...

  8. 一个定时器生成多路PWM波形的原理和方法成都自动化开发

    在很多工程应用中,需要使用到PWM波(脉宽调制),例如电机调速.温度控制调整功率等.本文讲述怎么利用单片机的一个定时器生成多路PWM波形. 一般的,PWM的周期t1是一个固定值,如1ms,10ms,1 ...

  9. Silverlight开发MMORPG游戏研讨(4):用一个定时器实现多个不同帧频的动画

    上一篇文章介绍了用CompositionTarget_Rendering实现固定时间间隔定时器.本篇将继续这个话题,介绍该定时器的一个实际应用:用一个定时器实现多个帧频不同的动画,笔者正在开发的MMO ...

最新文章

  1. android 闪烁发光动画,androidview动画发光效果在imageview上
  2. linux系统下怎样压缩文件,Linux操作系统下常用压缩文件如何解压?
  3. (四)Decorator设计模式解决GET/POST请求的乱码问题(转)
  4. 分享 | 光纤光缆布线基础知识及系统设计
  5. NYOJ 595 乱七八糟
  6. arm 流水线和pc值
  7. 关于 Angular 应用 tsconfig.json 中的 lib 属性
  8. POJ3468-A Simple Problem with Integers【线段树,树状数组,分块】
  9. android中tools的含义及用法
  10. php判断同一天,PHP判断两个时间戳是否在同一周同一月等 - YangJunwei
  11. (6)散列冲突处理:链地址法
  12. 决定创业失败的除了团队外
  13. Python中的闭包与参数引用域
  14. php curl 错误码,php,_PHP curl 错误 :curl__errno()返回错误码6,php - phpStudy
  15. CAD注记转ArcGIS注记并文字内容挂接进属性表(附插件下载)
  16. 其实你不懂我的芯--SIM卡的前世今生
  17. Julia两天极速入门学习笔记
  18. 想转行程序员,参加java培训班真的有用吗?
  19. 小程序api(常用)
  20. 双千兆网口路由器方案开发板香橙派R1 Plus LTS连接USB无线网卡测试说明(OpenWRT 系统)

热门文章

  1. java m4a文件拼接_面试官:为啥不提倡字符串拼接?看阿里java开发手册怎么说
  2. eval在类型转换的妙用
  3. df.isnull使用细节
  4. r 保留之前曲线_R简单数据处理和分析
  5. python中循环遍历字典
  6. php fpm 三个模式_php-fpm运行原理和模式的简单介绍
  7. 2016年8月份学习总结,读书《书都不会读,你还想成功》
  8. Python 工具链让你写的代码更规范
  9. Leaflet中使用markerCluster实现点聚合效果
  10. Three.js中引入dat.gui库实现界面组件控制动画速度变量