C# System.Threading.Timer 使用的两种方式

声明:本人纯小白一枚,对于timer的使用也只是了解甚微,这里的使用只是说明一下我用到的情况。顺便帮助跟我一样遇到困难的童鞋,对于定时器的用法,我掌握一般,所以如有错误欢迎指正,也希望大佬在评论区留下你们对于定时器的感悟,让我也学一手~

话不多说进入正题,定时器有三种,哪三种可以看这位大神的解释:

C#中三种定时器Timer的使用方法_c# timers.timer_武尚发的博客的博客-CSDN博客

这里主要说线程定时器,对于线程定时器可能出现的问题,见这位大神的解释:

c# 线程定时器 System.Threading.Timer_驰愿的博客-CSDN博客

我最初使用线程定时器的目的是利用其自动创建线程的方式避免阻塞,初用特爽,我的ui终于不卡顿了,可以为所欲为。这也就是第一种使用方式:

创建实例,在构造器中传入定时参数,就可以通过回调的方式不断执行我们设定好的方法。

但是随着需求的提高,我发现如果是一个短暂的定时,会出现多条线程同时运行,这个其实也没有问题,但是对于共同操作的数据,就会出现资源争夺的问题,比如大家都要往一个文件中写数据,线程A刚写一半,线程B继续要操作该文件,这就发生了资源争夺,网上有大神说各种方法,我是一个没学会啊。希望看到这篇的大神能帮忙讲解一下,跪谢~

幸不辱命,思前想后发现,是否可以单独创建一个线程执行定时器操作的同时,指定这唯一线程作为定时器回调执行的线程,这样尽管定时器执行方法变成单线程,但是确是独立于主线程之外的单独线程,并不会阻塞UI,发现可行,就查到了System.Timers.Timer的SynchronizingObject属性,发现貌似只能指定主线程(说实在的没看懂,等待大佬~)

不过,功夫不怕有心人,依旧找到了方法,也就是System.Threading.Timer的第二种用法:

我们可以将单线程的周期时间(构造器最后一位参数)设置为-1,也就是Timeout.Infinite,此时只会执行一次回调方法,而在回调方法的最后,再次改变定时器启动(改变定时器延时实现),change方法,同样,change第一个参数设置为回调启用时间,第二个参数设置为周期无穷,这样就可以实现单线程执行。

但是因为原本是多线程同时执行,现在又变成单线程执行,就会出现定时不准确的问题。这种方式让我意识到定时不能是静态的,必须是动态的。所以下面写串代码。展示我动态定时1s的方法

System.Threading.Timer timer = new Timer(CallBack,null,0,-1);//创建定时器实例,设置为立即执行回调方法

/* 回调方法 */
private void CallBack(object obj)
{
    DateTime start = DateTime.Now;
    /**/
    /*方法体代码。******/
    /**/
    double interval = (DateTime.Now-start).TotalMilliseconds;//回调方法执行全过程所耗费的ms数
    timer.Change(1000-interval,-1);
}

通过上述代码的方式可以做到动态调整定时时间的方法,达到精准延时,当然如果方法体执行时间大于线程间隔的话,会出现错误,这就不是代码的错误,而是设计定时的逻辑有问题了。此时如果依旧想要定时原本长度,也只有运行线程池的方式了,这种单线程运行的方法就不适用了。

再次声明,本人小白,求大神指教~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值