2016-09-20 123 views
1

在C#WinForms中,如果您打開一個對話框,它將不會在顯示對話框後繼續執行代碼,直到您單擊確定。這顯然是發生了什麼。但是,當對話框打開時,主線程仍然可以執行代碼。所以對話框沒有阻塞主線程,但它阻止了代碼的特定範圍。對話框如何阻止代碼執行而不阻塞主線程?

我很好奇這是如何工作的。可以/你會如何執行這樣的事情? (我不想這樣做,我只是意識到,我不完全理解對話框如何工作而不會阻塞線程執行。)

考慮這個示例代碼和帶有兩個按鈕和標籤的項目。標籤顯示計數器的值。計時器每500毫秒遞增計數器。其中一個按鈕打開一個對話框。另一個運行一個循環,調用Thread.Sleep一次十次。當對話框打開時,您會注意到標籤計數器增加,而thread.sleep會阻止所有定時器執行,直到完成。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace MainThreadPauser 
{ 
    public partial class Form1 : Form 
    { 
     int counter = 0; 
     public Form1() 
     { 
      InitializeComponent(); 
      System.Windows.Forms.Timer t = new System.Windows.Forms.Timer(); 
      t.Interval = 500; 
      t.Enabled = true; 
      t.Tick += new EventHandler(t_Tick); 
      t.Start(); 
     } 

     void t_Tick(object sender, EventArgs e) 
     { 
      BeginInvoke((Action)(() => { 
       AddToCounter(); 
      })); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      MyDialog dlg = new MyDialog(); 
      dlg.ShowDialog(this); 

      AddToCounter(5000); 
     } 

     private void AddToCounter(int value = 1) 
     { 
      counter += value; 
      label1.Text = counter.ToString(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      for (int x = 0; x < 10; x++) 
      { 
       Thread.Sleep(1000); 
      } 
     } 
    } 
} 
+0

UI活動正在主線程上發佈(或發送)消息的上下文中執行。 – bvj

回答

2

簡而言之:

您的GUI線程運行messagepump,它處理的點擊/移動/密鑰等信息。

當你打開一個模態對話框,在消息對話框將運行一個「新」 messagepump /對話框(while循環),因此所有的窗口消息處理,但它會阻止當前的方法,其中顯示內環在關閉對話框之前調用對話框。這就是爲什麼定時器(他們工作窗口消息)和重新繪製窗口仍然工作。該對話框將禁用你的窗口,所以你不能通過對話框。

+0

我知道消息系統,我只是沒有想到因爲某種原因,對話框會這樣做。所以我想知道是否有可能編寫我自己的消息泵模擬器。並不是說我想要一個真正的計劃,只是爲了科學/學習。 – teynon

+1

當然,它不是**明智的,而是一個'while(true)Application.DoEvents();'會做。當然有更好的方法,但這是一個容易的方法。你可以搜索'Windows.Forms'和'MessagePump'或'MessageLoop'。 _在那些日子裏(visual C++ 6.0),我們必須自己寫。 TranslateMessage/DispatchMessage等._ –