C#:如果 System.Windows.Forms.Timer 间隔不足以完成工作怎么办?

发布于 2024-09-07 01:57:35 字数 156 浏览 1 评论 0原文

首先,为我糟糕的英语写作感到抱歉。

假设我们有一个带有计时器的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

海未深 2024-09-14 01:57:35

你有几个选择,我能想到的有四个:

  1. 放弃当前的工作,开始新的工作。当然,这个最大的缺点是当前的工作无法停止。
  2. 等待当前作业完成,然后再开始新作业。如果每个作业都需要超过一分钟,这可能会导致您留下一系列待处理的作业。
  3. 不要开始新的工作。让当前任务完成,然后等待下一个计时器间隔开始新作业。
  4. 增加作业之间的间隔。这只是推迟问题的解决。

没有正确答案。您必须找出最适合您情况的方法。

我会选择#3 作为我的第一个解决方案。

You've got several options, here's four I can think of:

  1. Abandon the current job to start the new one. The big downside of this one is, of course, if the current job can't be stopped.
  2. Wait for the current job to finish before starting the new one. This might leave you with a queue of pending jobs if each one takes more than a minute.
  3. Don't start the new job. Let the current one finish and then wait for the next timer interval to start the new job.
  4. Increase the interval between jobs. This is just putting off the problem.

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.

不羁少年 2024-09-14 01:57:35

设置一个标志,允许您检查长时间运行的作业是否已完成,并且仅在完成后才运行该作业。不要忘记在完成长时间运行的作业后重置标志:

// field
private bool finishedWork = true;

public void Timer1_Tick(Object o, EventArgs e)
{
   if (finishedWork)
   {
     finishedWork = false;

     // do work

     finishedWork = true;
   }
}

另一种选择是在操作之间简单地禁用计时器:

public void Timer1_Tick(Object o, EventArgs e)
{
   if (finishedWork)
   {
     Timer1.Enabled = false;

     // do work

     Timer1.Enabled= true;
   }
}

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:

// field
private bool finishedWork = true;

public void Timer1_Tick(Object o, EventArgs e)
{
   if (finishedWork)
   {
     finishedWork = false;

     // do work

     finishedWork = true;
   }
}

Another option is to simply disable the timer between operations:

public void Timer1_Tick(Object o, EventArgs e)
{
   if (finishedWork)
   {
     Timer1.Enabled = false;

     // do work

     Timer1.Enabled= true;
   }
}
送你一个梦 2024-09-14 01:57:35

因此,在开始作业时设置一个标志,并在计时器触发时检查该标志。如果设置了该标志,则在计时器处理程序中不执行任何操作。请记住在作业完成后清除该标志。

您是否要分出一个工作线程来完成这项工作?

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?

ゃ人海孤独症 2024-09-14 01:57:35

另一个计时器事件可能会排队,导致 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.

尐籹人 2024-09-14 01:57:35

将流程的当前状态存储在字段或属性中,并且仅当状态不是“正在运行”时才启动流程。

Store the current state of the process in a field or property and start the process only if the state is no "running".

月棠 2024-09-14 01:57:35

在 Timer1_Tick 开始时禁用计时器,然后再次启用它?

Disable the timer at the start of Timer1_Tick and then enable it again afterwards?

冬天旳寂寞 2024-09-14 01:57:35

.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 in System.Windows.Forms namespace and another in System.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文