【问题标题】:How to improve the loading time of winform?如何提高winform的加载时间?
【发布时间】:2011-07-30 18:10:58
【问题描述】:

我有一个 WinForms 应用程序。主窗体有很多控件,这也是它加载速度很慢的原因之一。我想做的是使表单加载更快。

我已经设置了 beginupdate 和 endupdate。该表单没有在后台工作线程中呈现,因为这是主表单。没有初始形式。当用户单击应用程序图标时,这是加载的第一个表单。添加进度条或任何启动表单对我来说不是一个好主意。

我在这里检查了有关堆栈溢出的其他问题,但他们似乎没有遇到与我相同的问题。

如果您有一些示例/想法,如果您能与我分享,那就太好了。

【问题讨论】:

  • 我很难相信加载常规控件需要很长时间。不是其他东西加载缓慢吗?显示一些代码
  • 加载速度不是很慢,绘画需要很多控制才能完成。使用更少的控件。

标签: c# winforms


【解决方案1】:

一些建议:

  • 尽量减少 UI 的复杂性。您的用户会感谢您,您将可以加载更少的控件。例如,如果您有 3 或 4 个不经常使用的控件,您能否将它们移动到对话框或表单的折叠“高级”部分,以便推迟创建/显示它们?是否需要所有控件?真的吗?想想您要实现的工作流程——当前的控件集是实现工作流程的最简单方法吗?是否需要一次显示所有控件?也许您可以将它们放在选项卡控件中的单独选项卡上(因此实际上只在显示选项卡时创建控件)?

  • 你能减少使用的控制类型的范围吗?每种新类型的控件都可能导致您的程序加载新的 dll 来支持它。每个必须初始化的 dll 都会导致额外的启动时间。

  • 您是否使用了启动缓慢的控件?简单的文本字段会很快,但复杂的图形控件可能会很慢。

  • 加载了多少程序集(您自己的)?将所有代码合并到一个程序集中(例如使用 ILMerge),加载时间可能会大大缩短。

  • 删除所有不需要的初始化代码。你能简化初始化吗?是否可以推迟任何初始化(例如,仅在用户单击实际需要该数据存在的第一个按钮时创建一些成员变量,如果实际上还不需要,请不要尝试创建与数据库的连接等)

  • 您能推迟创建(部分)用户界面吗?例如,您可以将一组控件放入单独的 UserControl 表单中,然后在启动后不久以编程方式将此表单添加到 MainForm 中(例如在 Timer 上)。这将允许您的 MainForm 非常快速地出现,然后在不久之后使用其他控件“填充”,这可能不会改善实际启动时间,但它会“感觉”更快并且对启动响应更快。 (如果您的 MainForm 滚动并且那些额外的控件最初不在屏幕上,这种方法也非常有效,因为只有当用户向下滚动到足以看到它们时才需要创建它们)

  • 您是否正在显示任何可能加载缓慢的信息(例如,大型位图图像或从 SQL 服务器获取的数据)?您可以推迟加载它们或将其作为后台线程运行吗?使用压缩来加速加载?降低分辨率以尽量减少必须加载的数据量?预处理数据并将其存储在快速启动缓存中以供下次程序运行时使用?

  • 可以用优化的方法替换某些控件吗?例如您可以将“按钮栏”创建为一组 10 个单独的控件,或者创建为具有 10 个按钮外观的单个控件。使单个控件初始化和重绘比 10 个单独的控件要容易得多。

当然,一旦收集到最明显的低垂果实(甚至更早):

  • 在分析器下运行程序,看看它在哪里花费时间。

【讨论】:

  • 我运行了分析器,几乎 52% 的延迟是由于表单初始化造成的。我有一个类似 IDE 的环境,用户在任何给定时间都可能需要大量其他控件。这就是问题所在。
  • 不过我确实喜欢你的想法.. 将尝试实现其中的大部分.. 但是.. 我决定使用后台工作线程来帮助加载一些控件
【解决方案2】:

尽量减少在主窗体的on load 期间执行的代码或放置在主窗体上的任何控件。

您还可以探索NGEN,这是 Microsoft 的工具,有助于提高托管应用程序的性能

【讨论】:

  • 我确实使用过 NGEN。尽管加载 UI 的时间已经减少了,但我希望 UI 在用户启动应用程序后立即显示
  • 我检查了有无 ngen.. 没有 NGEN 的启动时间为 7225 毫秒.. 运行此 ngen 命令 ngen install 后启动时间减少了一半以上。现在是 3015.. 毫秒
【解决方案3】:

加载表单时,它会初始化其所有控件。
表单本身不会花费您很长时间。它是您的控件。

检查您的控件并检查其构造函数和初始化程序中可以改进的地方。

【讨论】:

  • 是的,它的控件.. 我正在使用一个对接库,一些 Krypton 控件。它们功能丰富,但也带有内存标签。已经看到其他一些应用程序使用相同的控件集,但加载速度非常快。我想知道我是否可以这样做......
【解决方案4】:

您是否需要立即使用所有控件?如果不是,也许您可​​以在某些事件触发后以编程方式加载它们,让您知道您需要该控件。

【讨论】:

    【解决方案5】:
    • 如果父控件有多个控件,请在初始化要添加的控件之前调用 SuspendLayout 方法。
    • 将控件添加到父控件后,调用ResumeLayout方法。这将提高具有许多控件的应用程序的性能。

    例如:

    private void LoadData()
    {
       // Suspend the form layout and load the data
       this.SuspendLayout();
       LoadMyData();   // logic to load your data will be here
       this.ResumeLayout();
    }
    

    解释:

    1. SuspendLayout() - 停止更新布局对象,因此组件不会花费任何时间进行重新绘制计算,直到布局恢复为止。
    2. ResumeLayout() - 完成所有更改后重新计算布局,从而提高性能。

    为什么要使用 SuspendLayout() 和 ResumeLayout()

    1. 当控件具有相互影响的布局属性时,它可以防止布局意外。
    2. 它可以调整多个与布局相关的属性,例如 Dock、Auto-Size 等。

    【讨论】:

      猜你喜欢
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多