将数据加载到 DatagGrid 时冻结 WPF UI



异步数据加载和整个过程中的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;
}

它冻结,因为您正在尝试更新 ProgressBtn,这是来自异步方法的 UI 控件。不确定是否从后台线程调用此方法。如果我要这样做,我会在 FetchInvoiceDataAsync(( 方法中引入一个回调来更新 ProgressBtn 控件。在该回调方法中,我将调用调度程序来更新 UI。这应该解决所有冻结问题。

Application.Current.Dispatcher.Invoke(() =>
{
// Set property or change UI compomponents.              
}); 

除此之外,我还建议使用ListCollectionView而不是可观察的集合。这将确保每次列表中有新成员时,都可以通过调用 refresh 来更新 UI。 希望这有帮助!

最新更新