更改表单的父线程

时间:2017-02-03 18:31:39

标签: c# winforms task-parallel-library .net-4.6

我正在尝试找到一种方法来将winform的线程的父级更改回GUI线程。现在我必须从另一个线程创建表单,但是从具有引用它的主窗体中访问变得不可能。

这里有我所拥有的样本

public partial class MainForm : Form
{
    // local instance of the sub form
    private ViewForm SubForm { get; set;} = null;

    public MainForm()
    {
        InitializeComponent();

        Task.Run(() =>
        {
            // set the sub form             
            SubForm = new ViewForm();
        }

        // call the rest of the initialization of main form
        InitializeCustomControls();
    }

    private void OpenViewWindow_Click(object sender, EventArgs e)
    {
        // if the window is instanciated
        if (SubForm != null)
        {
            SubForm.Show();                
        }
    }        
}

ViewForm窗口不是Form对象。这是一个自定义的第三方窗口。它有很多控件和模板与主题混合。单独调用一个新的空构造函数可能需要7秒,因此我需要在另一个线程上创建它,同时我继续加载我的主窗口。

现在我可以在窗口中调用除.Show()之外的任何方法,这些方法由于线程创建限制而总是失败。我想远离创建线程作为一个无休止的运行线程,它将等待并读取一些对象,告诉他何时显示和隐藏窗口。

.Show()错误:

Cross-thread operation not valid: Control 'ViewForm' accessed from a thread other than the thread it was created on.

我确实尝试了以下内容,但它仍然冻结了我的界面:

Task.Run(() =>
{
    // set the sub form   
    this.Invoke(new MethodInvoker(delegate
    {
        SubForm = new ViewForm();
    }));
}

我想要的是像火一样忘记GUI对象的实例化。

1 个答案:

答案 0 :(得分:0)

以下是使用BackGroundWorker

的解决方案
public partial class MainForm : Form
{
    // local instance of the sub form
    private ViewForm SubForm { get; set;} = null;

    public MainForm()
    {
        InitializeComponent();
        backGroundWorker1.RunWorkerAsync();
        InitializeCustomControls();
    }

    private void OpenViewWindow_Click(object sender, EventArgs e)
    {
        // if the window is instanciated
        if (SubForm != null)
        {
            SubForm.Show();                
        }
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        SubForm = new ViewForm();
    }
}

经过测试创建了两个表单,MainForm非常类似于示例中的表单,SubView表单在构造函数上带有Threading.Sleep(10000)