c#出现timer线程跑丢的情况,网上有说明需要线程重启来解决问题,请提供举例代码。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#出现timer线程跑丢的情况,网上有说明需要线程重启来解决问题,请提供举例代码。相关的知识,希望对你有一定的参考价值。

c#出现timer线程跑丢的情况,网上有说明需要线程重启来解决问题,请提供举例代码。

1。 System.Windows.Forms.Timer , 该 Timer 必须在 Winform 程序中使用,依赖于某个窗体。 因为该 Timer的时间由系统的Timer 消息发送到窗口,然后由窗口的 主 UI 线程进行处理。由于窗口的消息又先后顺序,并且处理的时候也是顺序同步的,因此当窗体的主ui线程正在执行其他的消息时, Timer的时间就会被丢弃。 由于该Timer时间的处理代码直接运行在窗体主UI 线程中,可以直接访问窗体上的控件。

2。System.Timers.Timer , 该Timer 与 System.Windows.Forms.Timer 原理机制比较相近,但是该Timer 不依赖于winform,可以是用在Component 或者一般的class里。并且该Timer的事件默认执行在一个线程池中的工作线程(worker thread)中。如果我们需要让代码执行在某个特定线程中(比如窗体的主UI线程),需要通过设置Timer的SynchronizingObject 属性。同时,由于这个Timer 会将所有的时间触发 event都 queue在一个队列中, 不会像 Windows.Forms.Timer 那样一但主消息线程忙,就会丢失事件。

3。System.Threading.Timer , 这个Timer 总的来讲是对具体应用环境以来最小的,所以可以在任何多线程环境中是用的Timer。 时间处理代码也是在线程池中的线程上执行。但是由于灵活性,它就没有提供很多现有的比如 直接访问 窗体控间,或者 通过设置 SynchronizingObject 属性 来指定执行线程。在对线程环境中我们需要自己编码来提供代码的同步,互斥等安全性。

上面的说明,表示只有第一种会有丢失现象,同时我们也能够接受。追问

System.Windows.Forms.Timer 跑几天了,在定时执行一些任务,跑几天进程还在,但是程序不执行了。程序是一直打开的,最早半天,或者3,4天timer 就没有反应了。求高手解决。

追答

如果可以DEBUG,那就附加进程DEBUG下。
要么就是通过写日志,来追踪问题所在

参考技术A 说下你的处理逻辑,或者代码发出来看下。通常资源不起冲突不会发生这种问题。追问

只是简单的从本地读取数据,然后存到远程mysql服务器上面。定时存取的。没有错误呀。但是System.Windows.Forms.Timer 跑着跑着也没有报错,就休眠了

追答

肯定是有异常的地方,导致在执行过程中出错,没有正常启动Timer,TryCatch加Log看下吧

关于C#中的timer控件!

比如,这个控件里面的语句执行比较复杂(执行时间比较长),
比如,这个空间的间隔是5秒钟,而里面的程序执行完毕需要10秒钟(比如是复制东西)。那最终会发生什么后果???复制过程会完成复制吗??
求解答!

会完成。但是需要注意:
1.System.Windows.Forms.Timer 是单线程的,它只在UI线程中运行,定时精度约55ms,当前的事件没处理完成时,下一次事件不会触发;过久地处理会导致界面假死。
2.System.Threading.Timer 是多线程的,触发的事件在ThreadPool里面的线程中运行,所以当前事件没处理完成时,也会另开一个新线程处理。追问

恩,回答的好透彻!很感谢……不过你说的System.Threading.Timer这个是控件吗??如何使用呢??我还是初学者。

追答

那是个类,不是控件,只能在代码中创建和使用。

参考技术A timer控件每到时间间隔后,会启动一个线程,执行Elapsed方法里的代码。
你所说的控件间隔是5s,执行语句需要10s,这不会有问题,因为他们是2个线程。除非你在这两个线程中使用了公共的变量,或使用了相同的io资源,会产生问题。
参考技术B 会完成复制吧。最后的效果也许是你延时5秒。拷贝东西10秒,再延时5秒,后面再干别的什么的。
也就是说你的间隔五秒要在第一次事件结束以后才开始重新计时。
参考技术C System.Threading.Timer 是一个类。不仅在窗体程序中可以使用,在控制台程序,在WINDOWS服务中都可以使用。
使用的大体代码如下:
System.Timers.Timer timer = new System.Timers.Timer();
timer.AutoReset = true;
timer.Interval = 1000d;
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

//时间到了之后处理的代码


其实用法和FORM里面的按个TIMER是一样的,你在FORM上把TIMER控件拖到窗体上之后可以看看窗体对应的那个designer.cs文件里相关的代码。
参考技术D 你需要用new thread,多线程处理,但是跨线程取值是比较麻烦的,最好能采用别的办法。
比如:先把timer关掉,执行程序,执行完,打开timer

以上是关于c#出现timer线程跑丢的情况,网上有说明需要线程重启来解决问题,请提供举例代码。的主要内容,如果未能解决你的问题,请参考以下文章

C#如何在BackgroundWorker 后台线程中使用定时器?

c#中Timer是单线程还是多线程

C# 计时器是不是在单独的线程上运行?

c#中Timer是单线程还是多线程?

关于C#中的timer控件!

C# 计时器用法(DispatcherTimerSystem.Timers.TimerSystem.Threading.Timer)