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# 关闭在另一个线程中打开的窗体_C#_Multithreading_Winforms - Fatal编程技术网

C# 关闭在另一个线程中打开的窗体

C# 关闭在另一个线程中打开的窗体,c#,multithreading,winforms,C#,Multithreading,Winforms,我的Winforms C应用程序遇到了一些问题。 我希望在主线程中的一些操作完成后,使名为的表单弹出关闭。该问题是由跨线程窗体关闭引起的异常 private void loginButton_Click(object sender, EventArgs e) { LoginProcess.Start(); // Running Form.show() in new thread ActiveAcc.IsValid = false; ActiveAcc.Usernam

我的Winforms C应用程序遇到了一些问题。 我希望在主线程中的一些操作完成后,使名为
的表单弹出
关闭。该问题是由跨线程窗体关闭引起的异常

private void loginButton_Click(object sender, EventArgs e)
{
    LoginProcess.Start();    // Running Form.show() in new thread
    ActiveAcc.IsValid = false;
    ActiveAcc.Username = userBox.Text;

    try
    {
        LoginCheck(userBox.Text, passBox.Text);
    }
    catch (IOException)
    {
        MessageBox.Show("..");
        return;
    }
    catch (SocketException)
    {
        MessageBox.Show("..");
        return;
    }

    if (ActiveAcc.IsValid)
    {
        MessageBox.Show("..");
        Close();
    }
    else
    {
        Popup.Close();      // Error caused by closing form from different thread
        MessageBox.Show("");
    }
}

public Login()             // 'Main' form constructor
{
    InitializeComponent();

    ActiveAcc = new Account();
    Popup = new LoginWaiter();
    LoginProcess = new Thread(Popup.Show);      //Popup is an ordinary Form
}
我一直在尝试使用各种工具,如
LoginProcess.Abort()
Popup.Dispose()
,使其正常工作,但即使应用程序在运行时环境中工作,由于引发的异常,它仍然不稳定。
如果有任何帮助,我将不胜感激。对于问题描述中的含糊不清,我深表歉意。

为什么不让UI线程执行UI任务,如打开和关闭表单,并生成另一个线程(或后台工作线程,或异步任务)来执行其他任务

在我看来,让其他线程尝试与UI线程上的元素交互(例如,让后台线程直接设置标签的文本或类似的内容)是令人心痛的

如果您只是必须保持代码的原样,那么可以做一件相当简单的事情。在弹出窗口中,添加默认为true的静态布尔值。同样在弹出窗口中,添加一个计时器任务,该任务每X毫秒检查一次布尔值的状态。如果它发现该值被设置为false,则让Popup告诉自己在该计时器内关闭

我对这个设计不感兴趣,但它可能看起来像:

 public partial class Popup : Form
    {
        public static bool StayVisible { get; set; }

        private System.Windows.Forms.Timer timer1;

        public Popup()
        {
            StayVisible = true;
            this.timer1.Interval = 1000;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!StayVisible) this.Close();
        }

    }
然后,从另一个线程,当您想要关闭弹出窗口时,调用

Popup.StayVisible = false;

更好的是,您可以触发弹出窗口将接收的事件,以便它可以自行关闭。由于您打算使用多个线程,因此必须处理

请看下面的内容来了解一下:或者,维护一个具有多个UI线程的应用程序是一种残酷的惩罚,我不希望对我最坏的敌人这样做。帮你自己一个忙,把你的应用程序限制在一个UI线程内。让UI线程执行所有UI工作,并在非UI线程中执行任何长时间运行的非UI工作。