我应该避免在winforms中的后台线程上做什么

时间:2009-03-22 03:20:03

标签: c# winforms

除了从后台线程更新GUI控件外,是否还有其他操作可以避免在winforms中的后台线程上完成?

4 个答案:

答案 0 :(得分:3)

哦,有很多陷阱。 BGW没有做太多工作来保护您免受线程编程的常见危害。并添加了一些自己的:

  • 从BGW和UI线程访问的变量必须受锁保护。
  • 不要更新BGW中的绑定数据源。控制更新将在BGW线程上完成,但不会生成异常。
  • 不要经常调用ReportProgress()。每秒执行超过1000次将冻结UI线程。大约25次/秒就足够了。
  • 小心使用userstate参数,您可以传递给ReportProgress()。通话结束后,BGW不得修改。
  • 不要在UI线程中循环IsBusy属性,它会死锁。
  • 当主窗体关闭时,BGW线程将被中止。注意必要的清理工作。
  • 请务必检查RunWorkerCompleted事件中的Error属性,它会在出现问题时告诉您。

答案 1 :(得分:2)

这有点广泛。如果你不需要,不要在后台线程中做任何事情;也就是说,不要仅仅因为你喜欢它而编写一些代码。在适当的地方使用线程,例如您不想中断GUI的长时间运行任务等等。此外,如果您最终只是从主UI线程调用Application.DoEvents()只是等待来自另一个线程的任务,您可能会考虑保留一个线程并在循环中以小块的形式完成工作,您将重新绘制GUI使用DoEvents()调用。这只是一个建议;但是,当然,很多时候需要创建多个线程。

也许您可以询问特定情况?

答案 2 :(得分:1)

那么,你不应该在后台线程上更新GUI控件的原因是GUI控件类不是线程安全的。因此,您可以概括:如果存在可能也使用它们的其他线程,请不要从后台线程中弄乱非线程安全类的实例。 (这很广泛,我知道,但任何打破这条规则的事都可能让你陷入困境)。

但我认为你的问题的关键在于你是否涵盖了Control.Invoke()创建的所有基础。如果是这样,是的,你有...... Control.Invoke专门设计用于控件不是线程安全的,因此,其他线程只应通过Control.Invoke()修改控件。

答案 3 :(得分:0)

我同意鲍比的看法,你的问题太宽泛了。相反,首先要假设如果你必须创建一个工作线程,除了绝对必须在那里以完成所需的任务之外,你不会在其中放置任何东西。