【发布时间】:2015-11-25 20:31:24
【问题描述】:
我正在为一个应该精确闪烁单词标签的表单编写代码。 它使用“expositionTime”在 X 毫秒内显示标签,并使用“intervalTime”在 Y 毫秒内隐藏标签。
该过程将重复 Z 次“numExpositions”,并在单击按钮后开始。 我的代码工作没有错误,我正在使用两个计时器来完成这项工作。 问题是在一些说明之后计时器变得不同步。
我的问题是,是否有一种解决方案可以让我进行精确的时间同步,其中展示时间(显示标签)和间隔(隐藏)将一起开始和结束 - 可能使用计时器在单独的线程上消逝或监控等待和如何实现它们。
我的部分代码使用了两个计时器:
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Timer timer2;
private static int counter = 0;
private static int numExpositions = 16;
private static int expositionTime = 2000;
private static int intervalTime = 1800;
// starts both timers that get desynchronized after some time
private void button1_Click(object sender, EventArgs e) { startTimer1(); startTimer2(); }
public void startTimer1()
{
timer1 = new System.Windows.Forms.Timer() { Interval = expositionTime + intervalTime };
timer1.Tick += new EventHandler(OnTimer1Event);
timer1.Start();
}
public void startTimer2()
{
timer2 = new System.Windows.Forms.Timer() { Interval = intervalTime };
timer2.Tick += new EventHandler(OnTimer2Event);
timer2.Start();
}
private void OnTimer1Event(object sender, EventArgs e)
{
if (counter >= numExpositions) // stops timers
{
timer1.Stop();
timer2.Stop();
wordLabel.Visible = false;
counter = 0;
this.Close()
}
else
{
wordLabel.Visible = true; // shows wordLabel
}
}
private void OnTimer2Event(object sender, EventArgs e)
{
wordLabel.Visible = false; // hides wordLabel
}
【问题讨论】:
-
我觉得这个问题不清楚。请解释为什么您首先使用两个同时运行的计时器。为什么不只启动一个计时器,然后当它过去时,再启动第二个?为什么,由于两个计时器的间隔不同,您是否期望它们即使在一次迭代之后仍会保持同步?您尝试过什么来解决您关心的任何同步问题?这个问题怎么不是 Stack Overflow 上许多现有问题的重复,涉及计时器和与实时时钟同步?
-
System.Windows.Forms.Timer并不准确。如果您想要准确,请尝试使用System.Timers.Timer或System.Threading.Timer,您可以找到所有差异here -
@SimpleVar:不过,这些计时器类都不是 100% 精确的。因为它们都有一个约定,即计时器不会早于给定的时间间隔触发,但可能会更晚,并且因为它们都受制于 Windows 线程调度的变幻莫测,所以它们都将具有相似的不精确性。为了在很长一段时间内保持精确,依赖时序的代码需要考虑外部时钟(例如计算机的实时时钟)。或者,可以选择只使用一个计时器,从该计时器运行多个活动。视情况而定。
-
@PeterDuniho 我同意。
Forms.Timer虽然 方式 不准确。我还会考虑只使用一个计时器并使用它 - 这是最简单且限制最少的选项,因为计时器并不一定要准确,因为它们只需要同步即可。 -
@PeterDuniho 我想我应该独立创建两个计时器,这样我就可以在其他进程中再次使用它们。我尝试使用锁定指令来同步它们,但也没有成功。事实是你是对的,Forms.Timer 不符合我的需要。最简单的解决方法是使用下面的答案。我还必须将异步添加到按钮单击方法。我将更多地研究这个案例以了解它是否不会给我未来带来任何问题。谢谢各位
标签: c# .net multithreading timer synchronization