【发布时间】:2020-11-17 18:51:14
【问题描述】:
我在一个窗口上有 2 个DataGrid,当您单击顶部 DataGrid 中的一行时,它会调用 CurrentChanged 事件以获取底部 DataGrid 的数据以显示该汽车品牌的模型。单击一行时 UI 会被阻止,因为该方法需要一段时间才能完成。如何让 async await 正常工作,以免 UI 被阻塞?
public class MainWindowViewModel
{
private ObservableCollection<Company> carCollectionOC = new ObservableCollection<Company>();
private ObservableCollection<Vehicle> vehicleOC = new ObservableCollection<Vehicle>();
private VehicleService vehicleService;
public ICollectionView CarCollection { get; set; }
public ICollectionView VehicleCollection { get; set; }
public MainWindowViewModel()
{
this.carCollectionOC.Add(new Company() { Brand = "Ford", Established = 1903 });
this.carCollectionOC.Add(new Company() { Brand = "Vauxhall", Established = 1857 });
this.CarCollection = new ListCollectionView(this.carCollectionOC);
this.CarCollection.CurrentChanged += CarCollection_CurrentChanged;
this.vehicleService = new VehicleService();
this.VehicleCollection = new ListCollectionView(this.vehicleOC);
}
private async void CarCollection_CurrentChanged(object sender, EventArgs e)
{
Company company = (Company)(sender as ICollectionView).CurrentItem;
this.vehicleOC = await this.GetVehiclesAsync(company.Brand);
}
private async Task<ObservableCollection<Vehicle>> GetVehiclesAsync(string carBrand)
{
this.vehicleOC.Clear();
foreach (var item in await this.vehicleService.GetVehicleListAsync(carBrand))
this.vehicleOC.Add(item);
Console.WriteLine("finishing GetVehiclesAsync");
return this.vehicleOC;
}
}
GetVehicleListAsync 是:
public Task<List<Vehicle>> GetVehicleListAsync(string carBrand)
{
for (var i = 600000000; i >= 0; i--)
{
// simulate a long process
}
return Task.FromResult(this.vehicleList.Where(item => item.Brand == carBrand).ToList());
}
【问题讨论】:
-
您的
GetVehicleListAsync实际上并不是异步的——它在调用它的线程上完成所有工作,然后使用Task.FromResult创建一个已经完成的Task。为了真正异步,GetVehicleListAsync需要快速返回,并返回尚未完成的Task。稍后当工作完成时,它将完成Task。如果您的“长进程”受 CPU 限制(不是 IO 限制,或使用 sleepds 等),那么使用Task.Run是将这项工作移至后台线程并返回Task的简单方法操作完成。 -
简而言之,我认为您应该多研究一下 async 和 await 模式和任务。您似乎在基础知识方面遇到了问题。在这个阶段进行一点研究将比这些问题更有益
标签: c# wpf async-await