简体   繁体   English

对话框如何在不阻塞主线程的情况下阻止代码执行?

[英]How do dialogs prevent code execution without blocking the main thread?

In C# WinForms, if you open a dialog box, it does not continue executing code after the show dialog until you click ok. 在C#WinForms中,如果打开一个对话框,则在单击“确定”之前,它不会在显示对话框之后继续执行代码。 This much is obviously what is happening. 这显然是正在发生的事情。 However, the main thread can still execute code while the dialog is open. 但是,在打开对话框时,主线程仍可以执行代码。 So the dialog box is not blocking the main thread, but it is blocking the specific scope of follow on code. 因此,该对话框不是在阻止主线程,而是在阻止代码的特定范围。

I'm curious how exactly this works. 我很好奇这是如何工作的。 Could / how would you implement something like this? 可以/您将如何实现这样的功能? (I don't want to do this, I just realized that I don't understand entirely how the dialog boxes work without blocking thread execution.) (我不想这样做,我只是意识到我不完全理解对话框如何在不阻止线程执行的情况下工作。)

Consider this sample code and project with two buttons and a label. 考虑此示例代码,并使用两个按钮和一个标签进行项目设计。 The label displays the value of a counter. 标签显示计数器的值。 A timer increments the counter every 500 milliseconds. 计时器每500毫秒递增计数器。 One of the buttons opens a dialog. 按钮之一将打开一个对话框。 The other runs a loop that calls Thread.Sleep for one second ten times. 另一个运行一个循环,该循环调用Thread.Sleep一秒钟十次。 You'll notice the label counter increments while the dialog is open, while the thread.sleep blocks all timer execution until it finishes. 您会注意到对话框打开时标签计数器增加,而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);
            }
        }
    }
}

In short: 简而言之:

Your gui thread runs a messagepump, it handles click/move/keys etc messages. 您的gui线程运行一个messagepump,它处理click / move / keys等消息。

When you open a modal dialog, the message dialog will run a 'new' messagepump/loop inside the dialog (while loop) , so all window messages are handled, but it will block the current method where the show dialog is called until you close the dialog. 当您打开模式对话框时,消息对话框将在对话框内部运行“新”消息泵/循环(while循环) ,因此将处理所有窗口消息,但是它将阻塞调用show对话框的当前方法,直到您关闭对话框。 Thats why timers (they work on windowmessages) and repainting the window is still working. 这就是为什么计时器(它们可以在windowmessages上运行)和重新绘制窗口的原因仍然起作用。 The dialog will disable your window, so you can't pass the dialog. 该对话框将禁用您的窗口,因此您无法通过该对话框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不阻塞主线程的情况下暂停 C# 代码执行? - How to Pause C# code execution without blocking main thread? 如何暂停线程池中线程的执行一段时间而不完全阻塞线程? - How do I pause execution of a thread in a thread pool for a certain amount of time without blocking the thread entirely? 如何在不阻塞主线程的情况下等待回调 - How to wait for a callback without blocking main thread 如何在不阻塞主线程的情况下实现 UDP - How to implement UDP without blocking main thread 如何在不阻塞主线程的情况下返回异步HttpWebResponse? - How to return an async HttpWebResponse without blocking the main thread? 如何在不阻塞主线程的情况下调用异步函数同步? - How to call an async function synchronized without blocking the main thread? 强制在主线程上执行代码 - Forcing code execution on main thread 只有当可选的主线程任务和工作线程完成时,我如何保证代码的执行? - How do I guarantee execution of code only if and when optional main thread task and worker threads are finished? 在不阻塞主线程的情况下等待一段时间 - Wait for a while without blocking main thread 阻止一个线程上的多个MessageBox而不阻塞 - Prevent multiple MessageBoxes on one thread without blocking
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM