我对线程的错误是什么?

时间:2012-08-01 13:09:06

标签: c# .net multithreading

梗概:

我正在尝试将非线程应用程序转换为线程应用程序。我在大约10年的时间里没有在应用程序中使用过线程,而且这个概念非常生疏。我只是抓不到的东西。你可以在代码前后查看我的(非常简短的),看看我做错了什么以及为什么这是错的?非常感谢所有帮助!谢谢!

看到的错误:

我的代码没有响应。我可以运行并执行按钮来启动应用程序,但不是启动新线程而只是工作,它们会冻结并显示“无响应”消息。我不确定我做错了什么。我是不是错误地实现了线程?

非线程代码:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
    //userform UserForm = new userform();
    //UserForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

断线代码:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(enumerationStuff);
    bg.RunWorkerAsync();

}
//run enumeration application in new thread
private void enumerationStuff(object sender, DoWorkEventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(correlationStuff);
    bg.RunWorkerAsync();
}
//run correlation application in new thread
private void correlationStuff(object sender, DoWorkEventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

3 个答案:

答案 0 :(得分:4)

BackgroundWorkers专为此而设计 - 在后台工作。它们不是为了显示新窗口或自己呈现任何UI而设计的 - 根据定义它们是前台工作。 BackgroundWorkers不处理任何消息,因此它们不会响应鼠标点击,键盘输入或任何内容,这就是窗口只显示“无响应”的原因。

很难回答这个问题,因为我并不清楚你在这里想要实现的目标。你的第一个非线程代码出了什么问题?

如果“个别应用程序”(实际上只是表单)冻结整个应用程序,他们可能在UI线程中做了大量的工作。在这种情况下,BackgroundWorkers可能是一个解决方案,但你在错误的地方使用它们。找到正在做“大量工作”的代码(无论是什么工作),看看你是否可以将该代码(只有那些代码)放入BackgroundWorker中。但是,你不能做的是在BackgroundWorker中对UI做任何事情 - 你只有一个UI线程(你开始的那个),只有那个线程可以触及UI。

答案 1 :(得分:2)

.NET / Windows用户界面不允许从单个用户界面线程执行任何操作的任何 UI操作。简而言之,UI本身是单线程的,而任何不接触UI的长时间运行操作都可以在辅助/后台线程中愉快地发生。

这就是为什么Control.Invoke之类的东西存在,以允许您在UI线程上下文中请求执行特定代码。

答案 2 :(得分:2)

这里的主要问题是你试图创造&在后台线程上运行GUI组件。鉴于您需要提示用户输入,我不明白为什么您要将此代码生成到单独的线程中。

让你的表单在UI线程中启动,然后将这些表单所做的任何额外工作传递给后台线程。