我有一个WPF应用程序,它显示DataGrid(XCeed DataGrid)中的项目。当数据库(SQLite)包含大量项目时,应用程序需要一段时间才能加载,因此我想使用yield return(如果可能)按需加载这些项目。我知道XCeed DataGrid supports UI virtualization,但我不完全确定如何转换以下的同步代码块。
目前,在BackgroundWorker中加载的列表可以防止UI减速,填充为网格的DataSource。
public override IList<IRecipe> GetRecipes()
{
List<IRecipe> recipes = new List<IRecipe>();
Execute(conn =>
{
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = "SELECT * FROM recipes ORDER BY Name";
var reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
var recipe = GetRecipe(reader);
recipes.Add(recipe);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error loading recipe: {0}", ex.Message));
}
}
reader.Close();
cmd.CommandText = "SELECT * FROM Ingredients WHERE Recipe = @Recipe";
cmd.Parameters.AddWithValue("@Recipe", string.Empty);
foreach (IRecipe recipe in recipes) {
cmd.Parameters["@Recipe"].Value = recipe.ID;
reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
IIngredient Ingredient = GetIngredient(reader);
recipe.Ingredients.Add(Ingredient);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error adding Ingredient to recipe '{0}': {1}", recipe.Name, ex.Message));
}
}
reader.Close();
}
}
另外还有其他方法可以提高速度并使用延迟加载吗?
答案 0 :(得分:2)
yield return
不是你的朋友。迭代器块(yield return
创建的)只是用于创建实现IEnumerable
的类的语法糖和实现状态机的自定义枚举器。这实际上并没有提供任何性能优势,也不一定有助于延迟加载,因为它生成的代码将与您在其中编写的代码同步。
我不是Xceed网格的专家,因此我无法为您提供特定于该产品的答案,但延迟加载可能确实有助于解决您的问题(要真正解决它,您可能会有加载尽可能少的数据来显示,然后开始抢先加载后台线程中的即将到来的数据,但是如何做到这一点的细节超出了答案的范围。)
一种方法可能是同步加载特定数量的行(当时需要显示的任何行),然后根据需要加载其余行(如果您的数据集很大且用户不太可能看起来在所有这些)或在后台(如果集合不大或用户可能会全部审查它们)。
答案 1 :(得分:0)
我并不熟悉xceed如何获取虚拟化项目 我假设它是通过某种事件来指定所请求的行范围。
在事件中(或使用的任何方法),您将获取一系列查询。请使用SELECT
documentation底部注明的LIMIT
和OFFSET
。