简体   繁体   English

如何从另一个线程中的表单关闭新线程上的表单?

[英]How to close a form on a new thread from a form which is in another thread?

I've been trying to figure this out for the past day or so. 在过去的一天左右的时间里,我一直在努力解决这个问题。

I have a program which has Form1, and a button that spawns Form2 in a new thread. 我有一个具有Form1的程序,以及一个在新线程中生成Form2的按钮。

I also have another button on Form1 that should close Form2, but since Form2 is in another thread, I cannot touch that object directly. 我在Form1上还有另一个按钮应该关闭Form2,但是由于Form2在另一个线程中,因此我无法直接触摸该对象。

I could do t.Abort() but that throws an exception. 我可以做t.Abort()但是会抛出异常。

How can I gracefully touch the other thread? 我如何才能优雅地触摸另一个线程? Do stuff to it? 做东西吗?

For example, how do I close the form from within Form1? 例如,如何在Form1中关闭表单?

I've searched google for "how to close a form from within another thread" and found several links hinting at Invoke and Delegate, but after trying some things, I obviously can't figure out how to use it properly. 我在Google上搜索了“如何从另一个线程中关闭表单”,并找到了一些提示Invoke和Delegate的链接,但是尝试了一些事情之后,我显然无法弄清楚如何正确使用它。

Can anyone help me to understand how it would apply to the code I have, so that I can understand how they can be used? 谁能帮助我了解它如何应用于我拥有的代码,以便使我了解如何使用它们? in which context, etc? 在什么情况下等等?

I've uploaded the project to github for your convenience: https://github.com/powercat/WindowsFormsApplication7/archive/master.zip 为了方便起见,我已将该项目上传到github: https : //github.com/powercat/WindowsFormsApplication7/archive/master.zip

-- -

Code: 码:

[Form1.cs] [Form1.cs中]

    public void FormThread()
    {
        Application.Run(new Form2());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(FormThread));
        t.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {

        //Need to close Form2 from here.

    }

[Form2.cs] [Form2.cs]

has the other form code. 具有其他表单代码。

In general, having two threads for two forms is not a good idea. 通常,为两种形式使用两个线程不是一个好主意。 It's almost always a better idea to have all of your forms on the main, UI thread, and move your logic and work onto background threads instead. 将所有表单都放在主线程,UI线程上,然后将逻辑转移到后台线程上,这几乎总是一个更好的主意。

That being said, if the Form is being run in the separate thread, you should be able to use BeginInvoke to close it: 话虽如此,如果Form是在单独的线程中运行的,则您应该能够使用BeginInvoke将其关闭:

 otherForm.BeginInvoke(new Action(() => otherForm.Close()));

Edit: 编辑:

In your case, you'd need to save the instance: 对于您的情况,您需要保存实例:

Form2 otherForm;
public void FormThread()
{       
    otherForm = new Form2();
    Application.Run(otherForm);
}

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(FormThread));
    t.SetApartmentState(ApartmentState.STA); // THIS IS REQUIRED!
    t.Start();
}

private void button2_Click(object sender, EventArgs e)
{
    //Need to close Form2 from here.
    if (otherForm != null)
    {
       otherForm.BeginInvoke(new Action( () => otherForm.Close() ));
       otherForm = null;
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM