应该第二个线程等待主线程

时间:2014-01-08 19:04:03

标签: c# multithreading

当我启动主线程时,我也启动了第二个线程,但第二个线程仍在等待主线程。我期望当我开始一个新线程时,它将在没有连接到主线程的情况下继续工作。那么为什么panel1在主线完成其工作后变得可见?

    private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
    {
        Thread thread = new Thread(new ThreadStart(threadUI));
        thread.Start();

        // This class is loading something from the server on the main thread
        excel.get_data_from_excel(comboBox1.SelectedItem.ToString(), this);
    }
    private void threadUI()
    {
        if (panel1.InvokeRequired)
        {
            panel1.Invoke(new newDelegate(threadUI));
        }
        else
        {
            panel1.Visible = true;
        }
    }

4 个答案:

答案 0 :(得分:5)

在主线程执行委托之前,Invoke方法不会返回。如果您希望后台线程继续而不等待主线程,请改为使用BeginInvoke

但是,请注意主线程上只能发生一件事。您可以调用Invoke或BeginInvoke,但在主线程空闲之前不会处理该委托。也就是说,如果get_data_from_excel需要很长时间,那么在get_data_from_excel完成之前,panel1.Visible=true将不会生效,comboBox1_SelectedIndexChanged_1将返回,并且主线程将变为空闲。

如果你真的想让这些东西“平行”,你必须在后台线程中执行get_data_from_excel。

答案 1 :(得分:1)

你正在UI线程中长时间运行非UI工作。

你创建的第二个线程除了调用Invoke并做一些工作外什么都不做。 Invoke 做什么在UI线程中运行一些代码,当前正在忙于做一些非UI工作。它将不会安排在该工作完成之后运行。

你应该做的是在另一个线程而不是UI线程中进行长时间运行的非UI工作。

答案 2 :(得分:0)

您似乎对Invoke()感到困惑。

Invoke()用于为显示panel1的线程排队委托。但是,Invoke() 会阻止UNTIL 该委托已完成运行。因此,您在Invoke()处阻止了第二个线程。

如果你想在主线程上运行一个动作,同时从第二个线程没有阻止调用它...然后使用BeginInvoke()。它会将代表排队,然后立即返回。

Servy的评论

Servy提出了一个很好的观点。什么是第二个线程的重点,如果它只是立即调用第一个?如果您要立即调整控件的属性,则无需创建第二个线程。

但看起来你正在从excel中获取数据。该部分代码应位于第二个帖子中......然后使用它BeginInvoke()输出。

答案 3 :(得分:0)

  

如果我使用这样的代码,它也在等待完整的下一个   线完成其工作

private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
    panel1.Visible = true;
    excel.get_data_from_excel(comboBox1.SelectedItem.ToString(), this);
}