【问题标题】:Windows Form Timer Vs Single Thread ApplicationWindows 窗体计时器与单线程应用程序
【发布时间】:2012-03-23 22:03:37
【问题描述】:

我有这个窗体,timer1 已启用,它的间隔设置为 2000 毫秒。 为什么表单每 2 秒显示一个消息框?我的意思是,当第一次调用 UI 线程的计时器滴答声时,会等到按下 OK 按钮,所以如果我不按下按钮,那么不应该出现另一个消息框。但它出现了!为什么?

我知道计时器在它自己的线程上工作,并且计时器在其间隔上调用 timer_tick 函数,问题是当 UI 线程在 mbox.show() 上被阻塞时如何显示另一个消息框?

  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
      MessageBox.Show("test");
    }
  }

【问题讨论】:

    标签: .net winforms multithreading timer


    【解决方案1】:

    Timer 创建自己的工作线程,它不会像主 UI 线程那样等待 OK 按钮。

    试试以下,有用吗? (现在无法查看抱歉)

    private void timer1_Tick(object sender, EventArgs e)     
    {       
        timer.Stop();
        MessageBox.Show("test");     
        timer.Start();
    }
    

    编辑:在 cmets 中回答问题

    所以如果主 UI 线程在 mbox.Show() 处停止,为什么另一个消息框 显示?

    this SO post

    MessageBox.Show 将在调用它的线程上显示 UI。如果有 还不是在线程上运行的消息泵,它将设置一个 临时的一个,以便发挥作用。之后会拆掉 显示通话完成

    【讨论】:

    • 如果主 UI 线程在 mbox.Show() 处停止,为什么会显示另一个消息框?
    【解决方案2】:

    这是因为您使用了 MessageBox。它是一个模式对话框,用于泵送消息循环。因此,所有正常的 Windows 通知仍会传递。比如绘画事件。它唯一阻止的是用户输入通知、鼠标和键盘。但不是定时器消息。 Form.ShowDialog() 方法也以这种方式工作。

    您必须自己禁用计时器。

    【讨论】:

      【解决方案3】:

      您需要在显示消息框时停止计时器,并在消息框关闭时重新启动它:

      private void timer1_Tick(object sender, EventArgs e)
      {
          this.timer.Stop();
          DialogResult result = MessageBox.Show("test");
          if (result == DialogResult.OK)
          {
              this.timer.Start();
          }
      }
      

      【讨论】:

        【解决方案4】:

        计时器在它自己的线程上工作,而不是在 UI 线程上,因此它不会被消息框对话框阻塞。

        您可以使用反射器看看它是如何工作的。

        【讨论】:

        • 我知道计时器在它自己的线程上工作,并且计时器在其间隔上调用 timer_tick 函数,问题是当 UI 线程在 mbox.show() 上被阻塞时如何显示另一个消息框?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多