[英]How do dialogs prevent code execution without blocking the main thread?
在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);
}
}
}
}
簡而言之:
您的gui線程運行一個messagepump,它處理click / move / keys等消息。
當您打開模式對話框時,消息對話框將在對話框內部運行“新”消息泵/循環(while循環) ,因此將處理所有窗口消息,但是它將阻塞調用show對話框的當前方法,直到您關閉對話框。 這就是為什么計時器(它們可以在windowmessages上運行)和重新繪制窗口的原因仍然起作用。 該對話框將禁用您的窗口,因此您無法通過該對話框。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.