none
System.Windows.Forms.Timer.Tick事件中多次MessageBox.Show() RRS feed

  • 问题

  • public partial class Form1 : Form
     {
     private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 
    public Form1() { InitializeComponent();
    timer.Interval = 1000; timer.Tick += new EventHandler(timer_Tick); timer.Start(); } void timer_Tick(object sender, EventArgs e) { Console.WriteLine("thread id: " + AppDomain.GetCurrentThreadId()); System.Windows.Forms.MessageBox.Show("Pause"); Console.WriteLine("msg box closed"); } }
    如果这是同一个线程?那为什么会弹出几次对话框,并且在我点击后,打印几次msg box closed的信息?
    
    
    
    

     

    相同的问题http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/a2af4016-e955-4ad4-9037-070d587ea935


    格子棋

    2011年5月6日 14:35

答案

  • MessageBox.Show不是阻塞操作,而是启动一个消息循环,不然你根本就看不到消息框。因为WM_PAINT没有处理。同样的,因为有了消息循坏,WM_TIMER也会被处理,所以你的tick函数会被重复进入。你可以在调试的时候在timer处理函数那里设置一个断点就可以看得很清楚了。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 Paul Zhou 2011年5月21日 3:15
    2011年5月7日 20:30
    版主

全部回复

  • ???有人告诉我这是为什么吗?

           线程阻塞后,下面的代码竟然还能执行???


    格子棋
    2011年5月7日 14:28
  • MessageBox.Show不是阻塞操作,而是启动一个消息循环,不然你根本就看不到消息框。因为WM_PAINT没有处理。同样的,因为有了消息循坏,WM_TIMER也会被处理,所以你的tick函数会被重复进入。你可以在调试的时候在timer处理函数那里设置一个断点就可以看得很清楚了。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    • 已标记为答案 Paul Zhou 2011年5月21日 3:15
    2011年5月7日 20:30
    版主
  • 你的意思是MessageBox.Show只是向消息循环发送一条消息,使操作系统绘制一个对话框吗?

    实际上,多次弹出对话框比较容易理解,但是,如下所示
    Console.WriteLine("thread id: " + AppDomain.GetCurrentThreadId());
    两次tick都在同一线程上面,而
    Console.WriteLine("msg box closed");
    却是在等待MessageBox.Show()执行完毕后输出。


    格子棋
    2011年5月8日 7:45
  • 不是。MessageBox不是向现有的消息循环发消息,而是启动另外一个消息循环,所以消息会被得到处理,而不是阻塞。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2011年5月9日 3:10
    版主
  • 哦    那为什么方法不是立即返回。。。而必须等到点击按钮后返回???
    格子棋
    2011年5月9日 13:48
  • 因为那是一个循环……

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2011年5月9日 14:57
    版主
  • 同一个线程里面执行写了循环的方法还能被重入???


    格子棋
    2011年5月12日 9:15
  • 越说我越不明白了。
    格子棋
    2011年5月12日 9:15
  • 因为被重入的函数是回调函数,可以被递归调用的。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2011年5月12日 14:27
    版主
  • 你自己写的循环当然不会重入。 但是 Timer 不一样,在你阻塞线程的时候依然在跳动,正如 Sheng Jiang 所言, 那是个回调函数。

     

    因此没到一次 Timer 的时间,需要执行的代码都会 Append 起来, 等到阻塞结束,立即执行。


    学习学习....
    2011年5月16日 5:02