【发布时间】:2019-02-02 06:14:39
【问题描述】:
异步数据加载和整个过程 UI 都是响应式的。但是当这条线InvoiceGrid.ItemsSource = results; 执行时,UI 会冻结一秒或更长时间,具体取决于数据的大小。有没有办法摆脱这个 UI 冻结?
private async void FetchInvoicesDataFunc(object sender, RoutedEventArgs e)
{
List<Invoice> results = new List<Invoice>();
ProgressBtn.Content = "Loading Data ...";
await Task.Run(async() => results.AddRange(await FetchInvoiceDataAsync(0, 500));
ProgressBtn.Content = "25% done...";
await Task.Run(async() => results.AddRange(await FetchInvoiceDataAsync(501, 1000));
ProgressBtn.Content = "50% done...";
await Task.Run(async() => results.AddRange(await FetchInvoiceDataAsync(1001, 1500));
ProgressBtn.Content = "75% done...";
await Task.Run(async() => results.AddRange(await FetchInvoiceDataAsync(1501, 2000));
InvoiceGrid.ItemsSource = results;
ProgressBtn.Content = "Loaded !";
}
private async Task<List<Invoice>> FetchInvoiceDataAsync(int start, int end)
{
List<Invoice> result;
using(var context = new Intelliventory_DBEntities() )
{
result = await context.Invoices.Where(b => b.InvoiceID >= start && b.InvoiceID <= end).Include(x => x.Customer).ToListAsync();
}
return result;
}
【问题讨论】:
-
是的。加载更少的数据。如果它冻结,则可能是因为您试图显示太多数据。使用分页或某种动态加载。没有人需要同时查看数以万计的记录。另外,永远不要写
await Task.Run(async () => ...)。写await results.AddRange(await FetchInvoiceDataAsync(1501, 2000); -
我知道我正在使用分页,但至少应该显示 100 行,它仍然会冻结一小段时间,我认为这很糟糕!
-
我认为 wpf 的 DataGrid 没有任何用于动态加载的内置选项。您可能想寻找其他一些支持动态加载的控件。也许写一个自定义的。
-
感谢先生的建议!即使上面的代码我也很难理解!
-
@FCin 写入
await results.AddRange(await FetchInvoiceDataAsync(1501, 2000);将不起作用,因为AddRange不会返回Task。如果他想将他的结果添加到 GUI 线程之外的列表中,那么解决方案就可以了。
标签: c# wpf async-await wpfdatagrid