立即显示启动画面

发布于 2024-11-02 20:06:31 字数 238 浏览 5 评论 0原文

我们正在处理 WinForm 应用程序的缓慢启动问题(它是一个大型应用程序,并且具有许多控制程序集)。控制组件是 DevComponent。应用Ngen来防止jit编译,但加载时间只是减少了一点。

该应用程序有一个启动屏幕,但它仅在应用程序启动后 12 秒内出现。有什么方法可以立即显示启动画面吗?

我们当前的建议是创建一个带有启动屏幕的轻量级应用程序,在单独的进程中运行主应用程序,并在主应用程序初始化完成后关闭轻量级应用程序。

We are dealing with slow start for WinForm applications (it is a large application and has many control assemblies). Control assemblies are DevComponents. Ngen was applied to prevent jit compilation, but the loading time just decreased a little.

The app has a splash screen, but it appears only in 12 seconds after the app has started. Is there any approach to show the splash screen at once?

Our current suggestion is to create a lightweight app with the splash screen, run the main app in a separate process, and close the lightweight app when initialization of the main app is done.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

错々过的事 2024-11-09 20:06:31

.NET 应用程序永远不会立即显示启动屏幕。
即使您已经对程序集进行了 NGen 处理以消除 JIT 编译时间,您仍然需要等待所有 .NET Framework DLL 加载到内存中。这是一个相当大的框架,冷启动时加载需要相当长的时间。对此你真的无能为力。

微软试图尽可能地减轻痛苦。 WindowsFormsApplicationBase(它的定义在Microsoft.VisualBasic 命名空间(但不要被它吓倒;它完全可以在 C# 应用程序中使用)提供了用于显示启动屏幕的内置机制。您所要做的就是设置其 SplashScreen属性 到适当的形式,其他一切都在幕后处理。即使在冷启动情况下,它也已针对最大响应时间进行了大量优化,但它仍然不会即时

您唯一的其他选择是在非托管代码中编写小型包装器,其唯一目的是尽快启动启动屏幕,然后调用 .NET 应用程序开始启动自身。当然,这里越轻越好。 C++ 是一种选择,但 C 可能是更好的选择。您需要最大限度地减少必须链接的外部库的数量,因此像 MFC 或 Qt 这样的框架肯定已经过时:您需要直接针对 Windows API。

Visual Studio 团队在 VS 2010 中做了类似的事情。他们对这个过程有一个非常有趣的解释 可在他们的博客上找到

尽管 Visual Studio 2010 使用 WPF 作为其主窗口,但使用 WPF 作为启动屏幕需要等待 CLR 和 WPF 初始化,然后才能在屏幕上绘制单个像素。虽然我们在 .Net 4.0 中对 CLR 和 WPF 启动速度做出了一些巨大的改进,但它仍然无法完全匹配原始 Win32 的性能。因此,我们选择保留本机 C++ 代码并使用 Win32 作为启动画面。

但我不会在这里花太多时间。由于您通常应该为用户提供打开和关闭启动屏幕的选项,并且大多数用户会选择将其关闭,因此很多人一开始就不太可能看到它。任何好的优化分析器都会告诉您它不值得优化。

You're never going to get a splash screen for a .NET application to show instantly.
Even if you've NGen'ed the assemblies to eliminate the JIT-compile time, you still have to wait while all of the .NET Framework DLLs are loaded into memory. It's a pretty large framework, and it takes a non-trivial amount of time to load upon a cold start. Nothing you can really do about that.

Microsoft has tried to ease the pain as much as possible. The WindowsFormsApplicationBase class (it's defined in the Microsoft.VisualBasic namespace, but don't let that scare you off; it's perfectly usable from a C# application) provides a built-in mechanism for showing a splash screen. All you have to do is set its SplashScreen property to the appropriate form, and everything else is handled behind the scenes. It's been heavily optimized for maximum response time, even in a cold-start situation, but it's still not going to be instant.

The only other option that you have is to write small wrapper in unmanaged code, whose only purpose is to throw the splash screen up as quickly as possible, then call your .NET application to start launching itself. The lighter the better here, of course. C++ is an option, but C is probably a better option. You need to minimize the number of external libraries that you have to link, so a framework like MFC or Qt is definitely out: you need to target the Windows API directly.

The Visual Studio team did something similar in VS 2010. They have a pretty interesting explanation of the process available on their blog:

Even though Visual Studio 2010 uses WPF for its main window, using WPF for the splash screen would require that we wait for the CLR and WPF to initialize before we could paint a single pixel on the screen. While we’ve made some tremendous improvements in CLR and WPF startup speed in .Net 4.0, it still can’t quite match the performance of raw Win32. So, the choice was made to stay with native C++ code and Win32 for the splash screen.

But I wouldn't spend too much time here. Since you should generally give users the option to turn splash screens on and off, and most users will opt to turn it off, it's unlikely that very many people will ever see it in the first place. Any good optimization profiler would tell you that it isn't worth optimizing.

南…巷孤猫 2024-11-09 20:06:31

有关用 C++ 编写并使用本机 Windows API 的轻量级、可重用的启动屏幕组件,请参阅 Stefan Olson 的启动画面。它采用 Cody Gray 提到的方法,从一个单独的非 CLR 进程开始,然后加载主 CLR 应用程序。

我必须在上一份工作中实现完全相同的事情,并且我可以确认该方法效果良好 - 用户单击开始菜单中的程序图标和出现启动屏幕之间的时间只有几毫秒,因此感觉“即时” '。

For a lightweight, reusable splash screen component written in C++ and using the native Windows APIs, see Stefan Olson's splash screen. It takes the approach Cody Gray alludes to of starting with a separate non-CLR process which then loads the main CLR app.

I had to implement the exact same thing at my last job and I can confirm the approach works well -- the time between the user clicking the program icon in the start menu and the splash screen appearing is just a few milliseconds and so feels 'instant'.

别再吹冷风 2024-11-09 20:06:31

我会说同意你目前的建议。

Winforms 应用程序不会显示,除非它已完全加载到内存中,并且由于这需要时间,我建议使用一个加载应用程序来显示启动画面并执行主要的大型应用程序(作为子进程)。

在大型应用程序中,加载时终止父应用程序。顺便说一句,这不会杀死孩子。

I'd say go along with your current suggestion.

The Winforms app will not show unless it has loaded completely into the memory, and since it takes time, I'd suggest having a loader application which shows the splash and executes the main huge app(as a child process).

In the huge app, terminate the parent app upon load. That won't kill the child, BTW.

一生独一 2024-11-09 20:06:31

我过去所做的快速而肮脏的方法是拥有两个应用程序,主应用程序和闪屏应用程序。主应用程序的所有重量级 DLL、控件等都是正常的。闪屏应用程序只是一个应用程序和一个 Windows 窗体,所有不必要的参考 DLL 从项目中剥离 - 事实上,您可以更进一步,使用更轻量级的 .NET 框架(如紧凑型 .NET 框架)或早期版本的 .NET 框架(如 1.X 或 2.0)。

您要做的就是启动闪屏应用程序并立即显示单个闪屏。有一个 Windows 窗体计时器(设置为 100 毫秒)并启用计时器作为窗体 Load 事件的最后一行。当计时器触发时,禁用计时器,然后启动您的实际应用程序。请参阅此讨论了解如何执行此操作。现在主应用程序将开始启动。一旦应用程序完成初始化并可能加载第一个表单,然后让主应用程序终止启动屏幕应用程序。有关终止应用程序的更多信息此处

The quick and dirty way that I have done in the past is to have two applications, your main application and your splashscreen application. The main application is normal with all of its heavyweight DLLs, controls, etc. The splashscreen application is simply an application and one Windows form, with all of the unneccesary reference DLLs stripped from the project - in fact you can take this one step further and make use a lighter weight .NET framework like the compact .NET framework or an earlier version of the .NET framework like 1.X or 2.0.

What you would do is have the splashscreen application startup and immediately show the single splashscreen. Have a Windows form timer (set for say 100 ms) and enable the timer as the last line of the form's Load event. When the timer fires, disable the timer and then launch your real application. See this discussion for how to do that. Now the main application will begin to fire up. Once the application is done with its initialization and perhaps loading the first form, then have the main application kill the splash screen application. More info on killing an application here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文