8

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

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

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

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

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

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

Edit2:我使用带有 System.Data.SQLite 和 EF4 的 .net 4 来加载数据。大约有 4000 行和 30 列。

4

3 回答 3

13

异步加载数据。加载时在 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-event 执行此操作。

更新

我不确定我是否正确理解您的问题。如果您的问题不是需要加载数据的时间,那么您的应用程序中有一些奇怪的地方。WPF 是 IMO 非常快。控件创建不需要很多时间。正如您在几毫秒内提到的那样,我将更大的列表可视化。

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

于 2011-01-18T13:52:27.530 回答
2

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

我学到的一个教训是,如果您使用 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。当用户进行需要持久化的更改时,我们使用存储库中的其他方法,然后仅加载实体的子集(即用户更改的实体)并应用必要的更新 - 一些验证由视图模型完成,可能还有其他验证通过约束/触发器等在数据库中进行。

于 2011-01-18T14:04:44.020 回答
0

这件事情是由很多原因导致的。

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

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

我看到应用程序在 wpf 中呈现 5M 条记录不到一秒。

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

于 2011-01-18T18:26:45.020 回答