如何在多个处理器核心之间平衡UI的负载?

时间:2012-10-23 13:12:41

标签: c#

我正在运行一个C#winform应用程序,它经常显示大量的统计信息和图表。此应用程序由多个表单组成,每个表单具有不同的输出。当我打开任务管理器并检查cpu使用情况时,我发现我的八个核心中只有一个核心超载,其余的都无所事事! 例如,有没有办法将每个表单数分配给核心。我需要提高性能。

我正在寻找的是多线程我的winforms,以便每个表单都有一个不同的核心运行的不同线程。这可能吗?

瓶颈是通过将数据加载到控件中而发生的。

3 个答案:

答案 0 :(得分:2)

在单个WinForms应用程序中可以有多个UI线程。每个UI线程都必须调用Application.Run(),并且您需要使用[STAThread]标记每个线程的入口点,就像在Main函数中一样。

我已成功完成此操作,并且在面对现有代码库时,这是一种合理的方法,该代码库在其UI线程上做了太多工作。但是......我想说这是一种可以通过其他方式改进的设计症状。如果你在UI线程上做了太多工作,想一想在其他线程上完成工作的方法。在我的应用程序中,我试图在非UI线程上完成所有非平凡的工作。它可以完成,但并不总是最快的交付软件的方式。

如果不做其他工作,单个UI线程就足以绘制8个充满数字和图表的屏幕,并且比人类可以跟上更频繁地更新它们。我知道情况如此: - )

答案 1 :(得分:0)

这在技术上可行,在WPF中比在WinForms中更灵活(根据我的经验),但在两者中都不推荐。 Windows客户端应用程序倾向于使用负责绘制UI的单个线程运行;通常,后台线程用于数据访问或业务逻辑的后台处理。此外,您必须在UI中进行大量工作才能将性能呈现为实际问题 - 这对我来说听起来像是不必要的工作。

然而,WinForms的基本风格是这样的:

var t = new Thread(() =>
        {
            var f = new Form1();
            Application.Run(f);
        })
t.Start();

您需要注意的事项:

  • 您将始终在表单之间进行Invoke次调用,以确保它们位于正确的主题上。
  • 如果您的业务层中有任何内容具有线程关联,那么每个使用它的表单都需要一个实例。
  • 应用程序关闭通常是在响应主线程的表单关闭时发生的。您可能需要手动处理关机,但使用上面的代码,您有两个消息循环正在运行,并且当另一个表单关闭时,它们将保持应用程序处于活动状态。

答案 2 :(得分:0)

如果您需要/想要,总是进行数据处理,从I / O接收,解析以及在单独的线程或多个线程上做什么。

然后,如果您要向UI控件加载大量数据,请确保不要经常与UI线程同步,例如,如果您分别从输入流调用每个项目,并且每个项目有数千个第二 - WinForms将陷入停滞。

将后台线程中的可视化数据更改队列并以最小间隔将它们批处理到UI线程,以便不经常这样做 - 线程同步很昂贵。 AddRange是你的朋友。