【问题标题】:C# precisely show label for X seconds and hide it for Y seconds [closed]C#精确显示标签X秒并隐藏Y秒[关闭]
【发布时间】: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.TimerSystem.Threading.Timer,您可以找到所有差异here
  • @SimpleVar:不过,这些计时器类都不是 100% 精确的。因为它们都有一个约定,即计时器不会早于给定的时间间隔触发,但可能会更晚,并且因为它们都受制于 Windows 线程调度的变幻莫测,所以它们都将具有相似的不精确性。为了在很长一段时间内保持精确,依赖时序的代码需要考虑外部时钟(例如计算机的实时时钟)。或者,可以选择只使用一个计时器,从该计时器运行多个活动。视情况而定。
  • @PeterDuniho 我同意。 Forms.Timer 虽然 方式 不准确。我还会考虑只使用一个计时器并使用它 - 这是最简单且限制最少的选项,因为计时器并不一定要准确,因为它们只需要同步即可。
  • @PeterDuniho 我想我应该独立创建两个计时器,这样我就可以在其他进程中再次使用它们。我尝试使用锁定指令来同步它们,但也没有成功。事实是你是对的,Forms.Timer 不符合我的需要。最简单的解决方法是使用下面的答案。我还必须将异步添加到按钮单击方法。我将更多地研究这个案例以了解它是否不会给我未来带来任何问题。谢谢各位

标签: c# .net multithreading timer synchronization


【解决方案1】:

一个更好的方法是这样的:

private async Task DoIt()
{
    for(int i = 0 ; i < numExpositions; i++)
    {
        wordLabel.Visible = true;
        await Task.Delay(expositionTime); //expositionTime is the number of milliseconds to keep the label visible
        wordLabel.Visible = false;
        await Task.Delay(intervalTime); //intervalTime is the number of milliseconds to keep the label hidden
    }

}

private void button1_Click(object sender, EventArgs e)
{
    DoIt();
}

这要求您使用 .NET 框架 4.5 或更高版本。

【讨论】:

  • 这如何解决 OP 在同步 两个 定时活动方面的困难?
  • @PeterDuniho,根据他在问题中的第一句话,OP 试图显示标签一段时间,然后将其隐藏一段时间,这正是这段代码的作用。据我了解他的要求,他尝试使用两个计时器不会给他想要的东西。
  • 恕我直言,我认为您不能说 what OP 正在尝试做什么。他的问题描述是“在一些说明之后”,而不是“在一次说明之后”。一次展示后,计时器已经不同步,所以如果他只关心这些,他肯定会这么说。很明显,您愿意做出假设,但这只是:假设。您答案中的代码实际上并没有与 OP 的代码做同样的事情,并且 OP 并不清楚他想要采取的行为有多远。
  • @PeterDuniho,据我了解的问题,最初的要求是隐藏和显示特定时间段的标签。 OP 选择使用两个计时器这一事实只是为了满足这一要求。我的回答是告诉 OP,他可以在不使用两个计时器的情况下满足他的原始要求。
  • @YacoubMassad 为了编译,你必须在按钮点击方法中添加async
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2019-12-27
相关资源
最近更新 更多