[英]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.