【问题标题】:C# Message Box Pops up Repeatedly in a TimerC#消息框在定时器中反复弹出
【发布时间】:2013-06-29 20:42:36
【问题描述】:

有人和我有类似的问题;但他们实际上并没有得到有效的答案。我可以通过创建一个 bool 并在它进入 if 语句后将其设置为 false 来使其工作。我在使用该方法之前已经这样做了,但是我想知道是否有更清洁的方法。

问题: 为什么当我在计时器中使用带有简单确定按钮的消息框时,必须有人单击确定?否则你每秒都会收到相同的消息?在下面的代码中;它每隔一秒弹出一次,因为这是计时器设置的操作(滴答一秒),但它应该只在计时器达到 10 时显示一次,如下面的代码所示,但计时器仍应“滴答”因为它显示在标签中。

在有人将我撕成碎片之前,因为我注意到人们出于某种原因喜欢在这里做事;我的逻辑是,由于秒 = 10,它应该显示一次。当 seconds = 11 时,它会显示一个额外的框是没有意义的,因为它是 11 而不是 10。我也想知道是什么原因造成的?

private void randomtimer_Tick(object sender, EventArgs e)
    {

        if (seconds == 10)
        {
            MessageBox.Show(this,"Why does this message display every one second over and over until someone clicks close or okay?");
        }
        seconds++;            
        if (seconds >= 60)
        {
            seconds = 0;
            minutes = minutes + 1;  
        }
        if (minutes >= 60)
        {
            minutes = 0;
            hours = hours + 1;
        }

        string niceTime = string.Format("{0:D2}h:{1:D2}m:{2:D2}s", hours, minutes, seconds); //format the time so it displays nicely
        label2.Text = "Session Length:\n" + niceTime;
    }

【问题讨论】:

    标签: c# messagebox


    【解决方案1】:

    简单的答案是,因为直到MessageBox.Show() 之后您才递增seconds。将它移到if (seconds == 10) 测试之前,您的代码就可以工作了。

    执行流程在MessageBox.Show() 处停止,然后触发另一个 Time 事件。当涉及到计时器时,您必须始终小心重新进入。

    【讨论】:

    • 这太简单了,太尴尬了。
    • 我认为您不需要比我包含的代码更多的代码 :)
    • 感谢您的快速回答。那确实解决了它。直到看到你说的我才想到。
    【解决方案2】:

    必须有人点击确定;否则你每秒都会收到相同的消息?

    现在,这是你的问题。再看代码:

    if (seconds == 10)
    {
        MessageBox.Show(this,"Why does this message display every one second over and over until someone clicks close or okay?");
    }
    seconds++;
    

    直到MessageBox.Show 被解除后,秒数才会增加。改成这样:

    if (seconds == 10)
    {
        seconds++;
        MessageBox.Show(this,"Why does this message display every one second over and over until someone clicks close or okay?");
    }
    else seconds++;
    

    这将解决您的问题。

    【讨论】:

    • 在这种情况下,它将在第 9 秒运行。你应该把它改成if (seconds == 11)
    • 是的;那确实解决了它。它以前发生在我身上;但它是间歇性的,现在我知道为什么了。也感谢您的快速回复。
    【解决方案3】:

    我会尽量简单地解释这一点。

    当定时器的处理程序被调用时,计数器不会被阻塞。您提供的功能每秒钟(计时器的间隔)都会运行。现在,当您显示MessageBox 时,计时器处理程序的线程被阻塞。因此,在用户单击 OK 并且函数恢复之前,您的增加秒数的代码不会运行。

    现在,如果用户不按 OK,则秒数将停留在 10。1 秒后,计时器将再次调用处理程序,并且您的 if 将运行,因为该值仍为 10。

    如果您想防止这种情况,请使用如下代码:

            if (seconds == 10)
            {
                seconds++;
                MessageBox.Show(this,"Why does this message display every one second over and over until someone clicks close or okay?");
            }
            else
                seconds++;
    

    当然有更好的方法,但这会奏效。

    【讨论】:

    • 不同意,这很可能是 GUI 线程上的 Windows.Forms.Timer。但它有自己的消息泵,所以事件仍然可以触发。
    • 这也是有道理的。我真的没有考虑过。虽然;添加每个消息框后,它仍然可以正确添加秒数。但我相信我确实明白你在说什么。仍然在学习一些东西。再次;谢谢(你的)信息。 :)
    • @tcarvin 感谢您的信息。我不知道它是否是 UI 线程。我可以编写一个使用另一个线程的计时器,而不会出现人们可能认为的问题,但最后我认为你是对的。我会试着为那部分想出一个更好的句子。
    • @tcarvin 我四处搜索,找不到具体的答案。我认为(并在我的回答中说)是System.Windows.Forms.Timer 有自己的计数线程,每当它达到间隔时,它都会调用 UI 线程上的处理程序。如果我正在编写计时器,我会这样做。
    • "定时器用于以用户定义的时间间隔引发事件。此 Windows 定时器是为单线程环境设计的,其中 UI 线程用于执行处理。它要求用户代码具有一个可用的 UI 消息泵,并且总是从同一个线程操作,或者将调用编组到另一个线程。”来自 MSDN msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 2011-10-28
    • 2019-12-02
    • 2017-05-29
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2022-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多