我是不是可以在 WPF MVVM 应用程序中使用 App Domains 来缩短启动时间,并且仅在需要时才加载程序集?
Posted
技术标签:
【中文标题】我是不是可以在 WPF MVVM 应用程序中使用 App Domains 来缩短启动时间,并且仅在需要时才加载程序集?【英文标题】:Can I use App Domains in a WPF MVVM application to improve start up time, and only load assemblies if I need them?我是否可以在 WPF MVVM 应用程序中使用 App Domains 来缩短启动时间,并且仅在需要时才加载程序集? 【发布时间】:2021-01-06 12:28:26 【问题描述】:我有一个 .net WPF 应用程序,随着更多功能的添加,它的加载速度越来越慢。我的客户想要添加更多功能。目前加载需要一分钟以上。
是否可以隔离程序集中包含的编码,例如“销售订单”,以便仅在用户导航到该视觉状态并加载该程序集中的视图和关联的视图模型时才加载它?
如果是,我有一些用于数据和文件 IO 类的通用程序集。它们是否可以在开始时加载并由每个 App Domain 共享,或者我是否需要在每个 AppDomain 中加载此程序集的本地副本。
假设这是可能的,应用程序的启动编码会是什么样子,以及在导航到需要它的可视状态之前如何加载程序集?
理想情况下,我希望在 10 秒内将我的应用程序加载到初始菜单,并且我不介意进一步延迟 5 到 10 秒,因为它们会加载应用程序的不同部分。
我只是不知道这是否可行
【问题讨论】:
这可能只是用户偏好,但有时最好在应用程序首次启动时承担所有加载,而不是稍后再触发 - 例如选择某个菜单项时。跨度> 如果它在 10 到 15 秒内加载就可以了。但是没有人愿意等待 60 到 80 秒,而且他们可能只会使用应用程序的一部分。这就是为什么我只想加载需要的内容。 【参考方案1】:我不确定多个 AppDomain 是否适合 WPF(IMO 绝对不是!)。如果您有复杂的功能,并且有很多功能,我建议您尝试执行某种用例分析并在较小的部分上拆分/分解并实施“延迟加载”。
当然,根据应用程序的类型,可能会发生在单用户会话期间(用户启动应用程序 > 执行他的任务/工作 > 使用关闭应用程序),例如100 个功能,用户可能会使用其中的 10 个。因此,在启动时,对剩余的 90 个功能(加载、初始化视图、视图模型、数据等)毫无意义。
其他词:
识别应用程序的功能并将它们表示为组件。我可以建议你看看这里: https://qube7.com/guides/controller.html
在上述解决方案中,控制器可能代表单个功能并封装该功能需要操作的所有内容。
识别用户在会话期间很有可能需要的功能,然后在启动时触发/运行代表这些功能的控制器。
其余功能视为按需:仅在用户明确请求时初始化、加载和运行代表控制器。
PS:您可以使用性能分析器(例如 ANTS)来查看您的瓶颈在哪里,但我敢打赌,程序集加载不会是最大的打击(程序集加载肯定不需要 60 秒):)
【讨论】:
【参考方案2】:另一个好主意,您可以在加载 UI 后立即对第二个 AppDomain 实现影子加载端程序集(在不同的线程中),这对用户来说会更舒服,因为他们可以在完全加载应用程序后立即访问他们的功能。 但是让我们看看你的应用程序。加载一个程序集需要时间,大约 300 毫秒,您还有多少个额外的程序集?你有没有用专门的追踪工具追踪过它?加载时究竟需要这么长时间?对于仅加载程序集来说,一分钟听起来太长了,可能还有其他逻辑需要它吗?
【讨论】:
我怀疑这是因为我正在使用 Infragistic 控件,这可能会增加很多开销 - 需要相当多的 IG 组件。 但是,我不知道从哪里开始使用 AppDomain,所以建议我将它们加载到单独的线程上是我所知道的又一个步骤。 @GordonIreland 如果加载需要很长时间,没有人愿意使用控件,我认为控件不会花费这么长时间。所以,我认为最好的办法是使用分析器并检查真正需要时间的东西。如果它是通过非最佳方式进行的,则可能是一些 wpf 控件大小计算。或者是其他东西。只有探查器确切地知道。我更喜欢 DotTrace,它有 2 周的试用期。【参考方案3】:我最终发现,通过使用反射来动态加载与所选菜单选项相关的特定用户控件,我可以显着加快加载时间。这将加载时间从 60 秒减少到 3 秒
App Domains 是一条红鲱鱼
【讨论】:
以上是关于我是不是可以在 WPF MVVM 应用程序中使用 App Domains 来缩短启动时间,并且仅在需要时才加载程序集?的主要内容,如果未能解决你的问题,请参考以下文章
在 WPF 智能客户端应用程序中使用 WCF DTO 时理解 MVVM 使用的问题
WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?