缩短感知的 WPF 应用程序启动时间

发布于 2024-10-12 07:16:16 字数 682 浏览 1 评论 0原文

我有一个 WPF 数据库查看器应用程序:它是一个简单的主窗口,其中包含一个带有数据网格的用户控件,该数据网格显示从 SQLite 数据库中提取的数据。
问题是该应用程序需要 6 秒才能启动才能使用。

我尝试在主窗口的构造函数中构建用户控件(并执行所有数据加载):
启动屏幕将以这种方式显示 5 秒,然后是 1 秒的空主窗口,直到应用程序准备好使用。
用户表示,需要很长时间才能(视觉上)发生某些事情。

然后,我将用户控件创建(和数据加载)移至主窗口的 Loaded 事件处理程序中: 启动屏幕将显示 3 秒,然后是 3 秒的空主窗口,直到应用程序准备就绪。
用户表示它“更好”,但不喜欢半完成的主窗口长时间显示为禁用状态。

是否有一些关于感知应用程序加载时间的一般建议,或者是否有任何其他关于如何改善这种情况的建议?
我相信理想情况下,主窗口将尽可能快地显示,以及一些沙漏或旋转器,直到加载数据。但是我不能只是将用户控件创建移到后台工作人员中,因为这将在错误的线程上完成。

有人对这个问题有什么建议吗?

编辑:
请注意,现在我刚刚指定了一个 LINQ-to-EF 查询作为网格数据源。
一种可能的改进可能是将此数据加载到后台数据表中,并仅在加载后分配它......

编辑2: 我使用 .net 4 与 System.Data.SQLite 和 EF4 来加载数据。大约有 4000 行和 30 列。

I have a WPF database viewer application: It's a simple main window containing a user control with a data grid showing the data extracted from an SQLite database.
The problem is that this application takes 6 seconds to start until it is usable.

I tried building the user control (and doing all the data loading) in the constructor of the main window:
The splash screen will be shown 5s this way, then followed by 1s of empty main window until the application is ready to be used.
Users said that it takes too long until something (visually) happens.

I then moved the user control creation (and data loading) into the Loaded event handler of the main window:
The splash screen will be shown 3s, followed by 3s of empty main window until the application is ready.
Users said that it is "better", but don't like the fact that a half finished main window is shown in disabled state for so long.

Is there some general advice to be found about perceived application load time or are there any other recommendations about how this situation can be improved?
I believe ideally the main window would be shown as fast as possible, along with some hour glass or spinner until the data is loaded. But then I cannot just move the user control creation into a background worker as this would be done on the wrong thread.

Does anybody have any suggestions to this problem?

Edit:
Note that right now I've just assigned a LINQ-to-EF query as the grid data source.
One possible improvement may be to load this data into a data table in background and assign it only once loaded...

Edit2:
I'm using .net 4 with System.Data.SQLite and EF4 to load the data. There are more or less 4000 rows and 30 columns.

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

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

发布评论

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

评论(3

终陌 2024-10-19 07:16:16

异步加载数据。加载时在 GUI 上为用户呈现一些不错的内容。以下代码可以帮助您解决此问题:

BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};  
bgWorker.DoWork += (s, e) => {      
    // Load here your file/s      
    // Use bgWorker.ReportProgress(); to report the current progress  
};  
bgWorker.ProgressChanged+=(s,e)=>{      
    // Here you will be informed about progress and here it is save to change/show progress. 
    // You can access from here savely a ProgressBars or another control.  
};  
bgWorker.RunWorkerCompleted += (s, e) => {      
// Here you will be informed if the job is done. 
// Use this event to unlock your gui 
};  
bgWorker.RunWorkerAsync();  

该应用程序并没有更快,但似乎快得多,因为 GUI 立即可见且响应迅速。也许您还可以在加载其余数据的同时向用户显示加载数据的一部分。使用 ProgressChanged 事件来执行此操作。

更新

我不确定我是否正确理解您的问题。如果您的问题不是需要加载数据的时间,那么您的应用程序中有些东西很奇怪。在我看来,WPF 非常快。控制创建并不需要很多时间。正如您提到的,我在几毫秒内想象了更大的列表。

尝试查看 UI 中是否有某些内容阻碍 DataGrid 虚拟化项目。也许你那里有问题。要分析 WPF 应用程序,我可以向您推荐 WPF 分析工具

Load your data asynchronous. Present something nice on the GUI for the user while loading. The following code can help you with this:

BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};  
bgWorker.DoWork += (s, e) => {      
    // Load here your file/s      
    // Use bgWorker.ReportProgress(); to report the current progress  
};  
bgWorker.ProgressChanged+=(s,e)=>{      
    // Here you will be informed about progress and here it is save to change/show progress. 
    // You can access from here savely a ProgressBars or another control.  
};  
bgWorker.RunWorkerCompleted += (s, e) => {      
// Here you will be informed if the job is done. 
// Use this event to unlock your gui 
};  
bgWorker.RunWorkerAsync();  

The app is not faster but it seems to be much faster because the GUI is immediately visible and responsive. Maybe you also can show the user a part of the loaded data while loading the rest. Use the ProgressChanged-event for doing this.

Update

I'm not sure if I understand your problem right. If your problem is not the time data needs to be loaded, then something is odd in your application. WPF is IMO very fast. Control-creation does not takes a lot of time. I visualize much bigger lists as you mention in some milliseconds.

Try to look if you have something in your UI that hinders the DataGrid to virtualize the Items. Maybe you have a proplem there. To analyse WPF apps, I can recommend you the WPF Profiling Tools.

秋意浓 2024-10-19 07:16:16

您可以做的最明显的事情就是分析您的应用程序并找到启动时间的瓶颈。听起来最有可能的罪魁祸首是从数据库加载数据。

我学到的一个教训是,如果您使用 ORM,在加载大型数据集时,如果您更喜欢 POCO(普通旧 CLR/C# 对象)而不是 ORM 生成的数据库实体(请参见下面的示例),则加载时间将是速度更快,RAM 使用量也会显着减少。原因是 EF 将尝试加载整个实体(即所有字段),并且可能加载与您的实体相关的整个数据,其中大部分数据您甚至不需要。您真正需要直接使用实体的唯一时间是在执行插入/更新/删除操作时。读取数据时,您应该获取应用程序需要显示和/或验证的字段。

如果遵循 MVVM 模式,上述架构并不难实现。

使用 EF 将数据加载到 POCO 的示例:

var query = from entity in context.Entities
                select new EntityPoco
                {
                    ID = entity.ID,
                    Name = entity.Name
                };

return query.ToList();

POCO 是非常简单的类,每个字段都有自动属性。

我们通常为应用程序中的每个实体都有存储库,每个存储库负责获取/更新与该实体相关的数据。视图模型引用了它们所需的存储库,因此它们不直接使用 EF。当用户进行需要持久化的更改时,我们使用存储库中的其他方法,然后仅加载实体的子集(即用户更改的实体)并应用必要的更新 - 由视图模型完成一些验证,并可能进行其他验证通过约束/触发器等在数据库中进行

The most obvious thing you can do is to profile your application and find the bottlenecks in start up time. It sounds like the most likely culprit will be the loading of data from your database.

One lesson I've learnt is that if you're using an ORM, when loading large datasets if you favour POCO (Plain Old CLR/C# Objects) over ORM-generated database entities (see example below), the load time will be a lot faster and RAM usage will be significantly decreased too. The reason for this is that EF will try to load the entire entity (i.e. all of it's fields) and possibly a whole load of data related to your entities, most of which you won't even need. The only time you really need to work directly with entities is when you're doing insert/update/delete operations. When reading data you should only get fields that your application needs to display and/or validate.

If you follow the MVVM pattern, the above architecture isn't hard to implement.

Example of loading data into POCOs with EF:

var query = from entity in context.Entities
                select new EntityPoco
                {
                    ID = entity.ID,
                    Name = entity.Name
                };

return query.ToList();

POCOs are very simple classes with autoproperties for each field.

We usually have repositories for each entity in our applications and each repository is responsible for getting/updating data related to that entity. The view models have references to the repositories they need so they don't use EF directly. When users make changes that need to be persisted, we use other methods in the repository that then load only a subset of entities (i.e. the ones the user changed) and apply the necessary updates - with some validation done by the viewmodel and possibly other validation going on in the DB via constraints/triggers, etc.

两人的回忆 2024-10-19 07:16:16

造成这种情况的原因有很多。

1) 部署机器的配置可能相当低。
2) 数据绑定不正确或有问题。

可能的解决方案是:
1)延迟加载数据
2)优化性能。 http://msdn.microsoft.com/en-us/library/aa970683.aspx

我曾见过应用程序在 wpf 中不到一秒就渲染 5M 条记录。

PS:还有一个最不可能的原因可能是 30 列,由于列顺序访问。

There are many reasons for this.

1) Deployment machine might have fairly low configuration.
2) In-Proper or problem with data binding.

Possible solutions would be:
1) Lazy load the data
2) Optimize the performance. http://msdn.microsoft.com/en-us/library/aa970683.aspx

I had saw applications render 5M records less than a second in wpf.

PS:One more least possible reasons may be 30 columns, due to column order access.

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