Dan*_*ane 5 c# wpf assemblies progress
我在显示加载到AppDomain.CurrentDomain中的程序集的进度时遇到了一些困难.
我想要做的是显示一个带有进度条的启动画面,我希望能够在每个程序集加载到AppDomain的内存中时更新此进度条.这样,用户将具有关于应用程序启动进度的可视指示符.
我不关心在渲染Splash Screen之前加载程序集,这实际上只是带有进度条的标准WPF窗口.加载启动画面后,我想在装载时报告它们.我没有手动加载这些程序集.
到目前为止,我已经使用以下标记处理了App.xaml中的Startup事件:
Startup="Application_Startup"
Run Code Online (Sandbox Code Playgroud)
启动后面的相应代码如下:
private void Application_Startup(object sender, StartupEventArgs e)
{
SplashScreen.Show<SplashScreen>();
AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
}
void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
SplashScreen.CallSplashScreenMethod<SplashScreen>(x => x.Text(args.LoadedAssembly.GetName().Name));
}
Run Code Online (Sandbox Code Playgroud)
这正如我所期望的那样,显示启动画面,并且在显示启动画面时正在加载的任何组件都显示在屏幕上而没有问题.

这里的问题是我看不到报告正在加载的程序集进度的方法.
程序集似乎没有按任何特定顺序线性加载,因此我不知道如何计算要加载的剩余程序集数量.我看不到一种明显的方法来获取当前正在加载的程序集.
如果我能得到一个尚未由CLR加载的程序集列表,我可以通过使用标准计数来实现进度条
progress = numberOfLoadedAssemblies / totalNumberOfAssemblies * 100;
Run Code Online (Sandbox Code Playgroud)
或者通过实施Chris Marisic关于使用加权平均值的优秀答案的逻辑
我不能做一个简单的" Directory.GetFiles().Length "来获取要加载的程序集总数.原因是因为CLR没有按任何特定顺序加载程序集.它似乎从应用程序根加载一些程序集,然后从GAC加载一些程序集,然后从应用程序根加载更多程序集.
我想知道的是,是否有办法获得要加载的剩余程序集列表.
正如其他人所说,您不能仅仅假设 10 个已加载的程序集中有 9 个就意味着 90%。但是,您可以使这些假设更加现实。
扫描将加载的所有程序集的文件信息,以便您了解每个程序集的文件大小。现在为“平均”装配创建一个加权值。
var totalSize = assemblies.Select(x=> x.FileSize).Sum();
var averageSize = totalSize / assemblies.Count();
var averageChange = averageSize / totalSize;
Run Code Online (Sandbox Code Playgroud)
假设您的进度条的范围是 0 到 1,您可以在averageChange每次加载另一个程序集时添加。
或者您可以实际计算加载的字节数与进度条的总大小。我个人会采用平均方法来防止单个程序集的进度条从 [--] 到 [--------------------]。用户不习惯非线性变化,也不太容易信任非线性变化。给他们一个线性增加的进度条,几乎在加载完成时结束,这会给人们一种事情正在工作并且很快就会完成的正确感觉。进度条不稳定的跳跃会让用户感觉系统不稳定且不可信。
我不能低估的一件事是,进度条很容易激怒用户。没有什么比进度条快速达到 99% 就停止了更让用户愤怒的了。这让他们感觉程序冻结了。他们还需要视觉指示来表明任何仪表之间的物体都没有冻结。他们也不想长时间坐着(请注意,这只是几秒钟)看到进度条填满然后又回到零。