4

概要:

我正在尝试将非线程应用程序转换为线程应用程序。我已经有 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();
}
4

3 回答 3

4

BackgroundWorkers 就是为此而设计的——在后台工作。它们并非旨在显示新窗口或呈现任何 UI 本身——根据定义,它们是前台工作。BackgroundWorkers 不处理任何消息,因此它们不会响应鼠标点击、键盘输入或任何事情,这就是窗口只显示“无响应”的原因。

很难回答这个问题,因为我不太清楚你在这里实际想要达到的目标。您的第一个非线程代码有什么问题?

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

于 2012-08-01T13:15:37.057 回答
2

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

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

于 2012-08-01T13:15:51.170 回答
2

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

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

于 2012-08-01T13:16:14.873 回答