C#:如果 System.Windows.Forms.Timer 间隔不足以完成工作怎么办?
首先,为我糟糕的英语写作感到抱歉。
假设我们有一个带有计时器的 win 表单 (C#)。计时器间隔已设置为 60000 毫秒。所以它的tick事件每1英里就会被触发一次。假设我们编写了一个名为 Timer1_Tick 的处理滴答事件的方法。如果作业需要超过 1 分钟才能完成怎么办?
First, sorry for my bad english writing.
Suppose that we have a win form (C#) that has a timer. The timer interval has been set to 60000 milsec. So its tick event will be fired every 1 milute. Suppose we have written a method that handles tick event called Timer1_Tick. What if the job needs more that 1 minute to complete?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
你有几个选择,我能想到的有四个:
没有正确答案。您必须找出最适合您情况的方法。
我会选择#3 作为我的第一个解决方案。
You've got several options, here's four I can think of:
There is no right answer. You'll have to work out what's best and works for your situation.
I'd go for #3 as my first solution.
设置一个标志,允许您检查长时间运行的作业是否已完成,并且仅在完成后才运行该作业。不要忘记在完成长时间运行的作业后重置标志:
另一种选择是在操作之间简单地禁用计时器:
Setup a flag that will allow you to check if the long running job has finished and only run the job if it has finished. Don't forget to reset the flag after finishing the long running job:
Another option is to simply disable the timer between operations:
因此,在开始作业时设置一个标志,并在计时器触发时检查该标志。如果设置了该标志,则在计时器处理程序中不执行任何操作。请记住在作业完成后清除该标志。
您是否要分出一个工作线程来完成这项工作?
So set a flag when you start the job and check the flag when the timer fires. If the flag is set, do nothing in the timer handler. Remember to clear the flag when the job completes.
Are you spinning off a worker thread to do the job?
另一个计时器事件可能会排队,导致 Timer1_Tick 在返回后几乎立即再次被调用。 (IIRC,不过,计时器滴答声是优先级最低的消息之一,因此它可能会首先处理排队到该点的任何其他消息,除了绘制消息之外)。
请注意,如果您的函数运行时间超过 2 分钟,则队列中可能只有最新的报价。
如果您的报价处理时间比计时器间隔长,您应该考虑提高间隔。无论哪种方式,您可能应该在后台线程中完成工作,并确保如果最后一个刻度的任务未完成,则不会启动另一个线程。否则,您最终可能会遇到成群的线程,它们都互相减慢速度,直到您的程序在其自身重量下崩溃。
Another timer event will likely be queued, causing Timer1_Tick to be called again almost immediately after it returns. (IIRC, though, timer ticks are one of the lowest priority messages, so it'll probably handle any other messages it's had queued up to that point first, except maybe paint messages).
Note, if your function takes longer than 2 minutes to run, it's possible (read: likely) that only the latest tick will be in the queue.
If your tick processing takes longer than the timer interval, you should look into raising the interval. Either way, you should probably be doing the work in a background thread and making sure you don't start another thread if the last tick's task isn't done. Otherwise you could end up with hordes of threads all slowing each other down til your program collapses under its own weight.
将流程的当前状态存储在字段或属性中,并且仅当状态不是“正在运行”时才启动流程。
Store the current state of the process in a field or property and start the process only if the state is no "running".
在 Timer1_Tick 开始时禁用计时器,然后再次启用它?
Disable the timer at the start of Timer1_Tick and then enable it again afterwards?
.Net 中有多种类型的计时器:一种位于 System.Timers 命名空间中,另一种位于 System.Windows.Forms 命名空间中,另一种位于 System.Timer 命名空间中。线程。
System.Windows.Forms.Timer 控件基于 UI 线程和消息循环,这意味着它将对计时器事件进行排队,如果您的处理程序超过间隔,它将在结束后立即调用。
另外两个定时器基于线程,并且非常准确。时间过去后,他们将重新进入您的处理程序。
There are multiple types of Timers in .Net: One is in a
System.Timers
namespace, another is inSystem.Windows.Forms
namespace and another inSystem.Threading
.The
System.Windows.Forms.Timer
control is based on UI thread and message loops, meaning it will queue the timer events and if your handler exceeds the interval, it will be called immediately after ending.The other two timers are based on threading, and are very accurate. They will reenter you handler after the time elapsed.