【问题标题】:Loading Windows form with over 200 controls使用 200 多个控件加载 Windows 窗体
【发布时间】:2010-09-08 18:13:48
【问题描述】:

我的表单有 200 多个控件! 加载表单和绑定控件大约需要 7 秒。

我已经用一些性能分析器跟踪了应用程序,但是除了构造函数的形式之外,我没有找到任何带有 HOT 标志的东西。

我想知道是否可以调用 InitializeComponent 方法,例如 backgroundWorker(多线程)!?

【问题讨论】:

  • 如果您有一个包含 200 多个控件的表单,那么您做错了。
  • 200 多个控件如何适合单个显示器?
  • 我怀疑您是否有可以监督 200 个控件的用户。普通用户有 10 个问题。
  • 我能想象得到 200 多个控件的唯一方法是,如果您试图让多个控件表现得好像它们是一个控件(想想四个按钮组合成一个方向键等)。如果您正在做类似的事情,请考虑改为编写自定义控件。如果您觉得用户可能想要在一个屏幕上执行 200 多项操作,您还应该尝试简化和改进您的 UI。
  • 遵循 Jesse 的轨迹...从管理的角度来看,将逻辑组封装到用户控件中会有所帮助。使用 20 个控件优化表单创建和加载过程是可行的……200 个可能会让你发疯。

标签: c# .net winforms multithreading loading


【解决方案1】:

不,线程不会帮助你。需要在 UI 线程上创建控件才能使应用程序正常工作。

唯一合理的方法是查看您是否真的需要在创建表单时创建所有 200 个控件,或者是否可以让它们“按需”加载。

在不了解您的应用程序的情况下,不可能提供更具体的指导,但也许您遇到的情况并非所有控件都同时使用,而是存在某种分页。如果是这样的话,每个“页面”也许可以做成一个用户控件,以便您可以根据需要加载和卸载页面。

【讨论】:

    【解决方案2】:

    一个更好的主意是使用 TabControl 拆分您的 UI。它内置了延迟加载。

    MSDN

    标签页中包含的控件在标签页显示之前不会创建,并且任何 在显示标签页之前,不会激活这些控件中的数据绑定。

    而且该设计直接针对您的问题。

    【讨论】:

    • 真的是延迟加载吗?我怀疑...但我不知道,现在最好检查一下。
    • 每个标签有 10 个控件,即 20 个标签。
    • @BoltClock,使用 TabPages 上的 TabControls,问题很快就会消失。这是一个 O(log n) 问题。
    【解决方案3】:

    性能不是您唯一的问题。操作系统对进程可以拥有的句柄数量有限制,并且对 WinForms 将执行的嵌套控件布局也有限制。如果您在一个窗口上有 200 多个 Windows 窗体控件,我敢打赌您会遇到这些限制和其他限制。

    我建议更改您的表单以减少控件:分页、虚拟化、延迟加载是您可以用来改进 UI 和性能的一些技术。

    【讨论】:

      【解决方案4】:

      其他人没有提到的尝试:

      • 取消 InitializeComponent 的 [DebuggerStepThru] 选项,然后您可能会更容易看到哪些项目花费的时间更长(使用分析器或只是在加载 20 倍期间在 IDE 中随机点击“暂停”并记住它最停止的位置)。
      • 如果您的老板允许,请转换为 WPF。
      • 从初始化组件和剪贴板上获取表单 InitializeComponent 的项目。添加一个带有 20MS 滴答声的计时器。在滴答声中,增加一个计数器。通过将您的 initializecomponent 代码拆分为包含 200 个案例的 select 语句,为每个刻度添加一个控件。在 201 停止计时器。这样用户就可以在添加所有控件之前开始工作。您将不得不重新排列控件。添加以便它们显示出来。您必须首先显示重要的控件。您将无法在设计器中修改表单。最后,我很同情那些认为这个要点根本不是玩笑的傻瓜。

      【讨论】:

        【解决方案5】:

        我相信 NGen-ing 您的应用程序可以大大提高性能。大多数这些控件(其中一些可能在您的应用程序中自定义)需要进行 NGen 编辑,这通常需要很长时间,因为回到相同的表单总是要快得多。

        【讨论】:

        • 我没试过,但 7 秒闻起来更像是数据(基础)绑定问题,而不是 JIT 延迟。
        • 嗯,它似乎是 windows 窗体而不是 WPF,所以不确定他是否使用数据绑定。
        【解决方案6】:

        虽然我可能同意 Judah 的观点,但我在 MDI WinForms 应用程序中看到了许多表单,这些表单逻辑上包含的控件总数远远超过 200 个,并且该表单需要每个控件来完成其工作。例如,发票输入窗口将有一组标题控件,然后是一组用户控件,每个控件都映射到发票行,并具有 SKU、描述、数量、单价、扩展价格、单位税等字段。这样一个窗口的控件计数取决于发票行的数量,如果天真地完成,一个大订单可能会生成一张需要数千个控件绑定和呈现在单个屏幕上的发票。为运输说明、税务信息、延期交货状态等添加更多的每行详细信息,并且尝试预加载和呈现窗口加载的每个控件会使应用程序崩溃。

        不过,7 秒似乎太长了。我同意弗雷德里克的观点;第一步是查看是否必须渲染所有 200 个控件才能显示单个屏幕的信息价值。使用选项卡控件以及用于“延迟加载”每个选项卡上显示的信息和控件的选项卡更改的事件处理程序是一个很好的第一步。如果您显示重复的子信息行(例如发票上的发票行),您可以通过一次加载有限的信息页面来节省时间;加载 10 行比加载 100 行要便宜得多,虽然在与数据库通信和动态加载控件时会产生一些开销,这些控件会以这种方式更频繁地重复,但与等待几秒钟以查看任何内容加载相比,这似乎微不足道窗口。

        【讨论】:

          猜你喜欢
          • 2013-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多