Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何中止ShowDialog中调用的线程_C#_Multithreading_Showdialog - Fatal编程技术网

C# 如何中止ShowDialog中调用的线程

C# 如何中止ShowDialog中调用的线程,c#,multithreading,showdialog,C#,Multithreading,Showdialog,让C#Windows窗体应用程序具有辅助线程,该线程接收来自外部系统的显示或隐藏窗体/对话框的请求。我知道辅助线程没有消息循环机制。我知道ShowDialog有自己的消息循环,因此次线程可以调用它,但是次线程会被阻塞,直到表单关闭,因此无法响应稍后隐藏表单的请求。问题是,如何让次线程显示的表单隐藏[或再次可见]。尝试在次线程上调用中断,但这不会中断或中止ShowDialog。除了调用Close的ShowDialog UI回调之外,没有任何内容会中止ShowDialog。实际上,两个窗体共享相同的

让C#Windows窗体应用程序具有辅助线程,该线程接收来自外部系统的显示或隐藏窗体/对话框的请求。我知道辅助线程没有消息循环机制。我知道ShowDialog有自己的消息循环,因此次线程可以调用它,但是次线程会被阻塞,直到表单关闭,因此无法响应稍后隐藏表单的请求。问题是,如何让次线程显示的表单隐藏[或再次可见]。尝试在次线程上调用中断,但这不会中断或中止ShowDialog。除了调用Close的ShowDialog UI回调之外,没有任何内容会中止ShowDialog。实际上,两个窗体共享相同的消息循环

每个处理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调用中创建一个委托,而不是一行程序。

也许您可以在对话框代码本身内部实现一个适当的回调?Invoke正在阻塞。显示模态会使情况变得更糟。但是BeginInvoke并没有阻塞。您试过了吗?您必须使用
ShowDialog()
?您可以改用
Show()
吗?或者HTEJ2--“在对话框代码本身内部”意味着操纵.NET实现?ZorgoZ--将尝试BeginInvoke,谢谢。