如何中止调用ShowDialog的线程

时间:2018-08-24 20:14:31

标签: c# multithreading showdialog

具有带有辅助线程的C#Windows Forms应用程序,该应用程序从外部系统接收显示或隐藏表单/对话框的请求。我了解辅助线程没有消息循环机制。我知道ShowDialog有其自己的消息循环,因此辅助线程可以调用它,但是辅助线程随后被阻塞,直到窗体关闭,因此无法响应以后的请求以隐藏该窗体。问题是,如何使辅助线程显示的表单隐藏(或再次变得可见)。尝试在辅助线程上调用“中断”,但不会中断或中止ShowDialog。除了ShowDialog UI回调(调用Close)之外,没有任何东西可以中止ShowDialog。

1 个答案:

答案 0 :(得分:1)

实际上,两种形式共享相同的消息循环。

每个处理gui的代码必须在同一线程(处理gui部分)上运行。 您需要的是使用BeginInvoke在该线程上运行命令。

我制作了一个只有一个简单按钮的示例应用程序,当您按下它时,启动了一个线程,该线程休眠3秒,然后打开对话框并再次休眠,然后再次关闭它,依此类推。

这是主窗口的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    Thread t;
    Form2 f2;

    private void button1_Click(object sender, EventArgs e)
    {
        t = new Thread(ThreadMethod);
        t.Start();
        button1.Enabled = false;
    }

    private void ShowForm()
    {
        f2 = new Form2();
        f2.ShowDialog();
    }

    private void ThreadMethod()
    {
        for (; ; )
        {
            Thread.Sleep(3000);
            if(f2 == null)
            {
                BeginInvoke((Action)(() => { ShowForm(); }));
            }
            else
            {
                f2.CloseMe();
                f2 = null;
            }
        }
    }
}

然后是用作对话框的表单代码:

using System;
using System.Windows.Forms;

namespace QuestionTesting
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public void CloseMe()
        {
            BeginInvoke((Action)(() => { Close(); }));
        }
    }
}

这只是简单的代码,可以根据需要进行调整。您可以创建一个委托,然后在BeginInvoke调用中使用该委托。