多个UI线程- Winforms

本文关键字:Winforms 线程 UI 多个 | 更新日期: 2023-09-27 18:09:54

我想在我的应用程序中创建多个UI线程。我模拟了下面的场景。我正在创建一个新的窗口/窗体上的按钮点击在一个背景线程

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var thread = new Thread(() =>
            {
                Form f = new Form();
                Application.Run(f);
            });
            // thread.IsBackground = true; -- Not required. See Solution below
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
    }  
}

注意-我正在做IsBackground = true,因为当用户关闭主窗体时,子窗体/窗口也应该关闭。是否有更干净/优雅的方式来实现相同的目标?

编辑-我想为每个窗口创建专用的UI线程。我将有10个这样的窗口并行显示实时数据。

解决方案 -这样行吗?(根据msdn和Hans的评论)设置公寓状态(见上面的代码)

protected override void OnClosed(EventArgs e)
{
    Application.Exit();
}

多个UI线程- Winforms

乱搞线程迟早会害了你。

从MSDN:

Windows窗体中的控件被绑定到一个特定的线程,并且不是线程安全的。因此,如果从其他线程调用控件的方法,则必须使用控件的调用方法之一将调用封送到适当的线程

你当然可以随心所欲地使用多个线程,但不要试图创建一个变通方法,以便能够使用不同的线程来更新UI。在你的工作线程/后台线程中使用Invoke/InvokeRequired

使用扩展方法使它更清晰:自动化invokerrequired代码模式

我认为你需要将线程的公寓状态设置为单线程,就像这里的ApartmentState for dummies和这里的thread -safe Form所示。Show: t.SetApartmentState(ApartmentState.STA)。我不知道这在后台线程中是否可行。

另一件事,我要敦促你看看MDI(多文档接口,例如在这里)。您是否真的需要将不同的表单显示为一个单独的窗口,或者它们更像是一个公共表单中的文档?当然,您可能有理由创建多个UI线程。

您可以处理MainForm。关闭事件并调用子表单。关闭(封送到正确的线程上)每个子表单。

我不知道为什么你想在单独的线程上的形式,虽然。难道你不能在主线程上以非模态方式显示子窗体吗?