【发布时间】:2018-06-22 08:55:00
【问题描述】:
我正在编写 WPF 应用程序,最近开始使用 await/async,因此 GUI 线程不会执行任何耗时的操作。
我的问题是我想使用实体框架从 db 异步加载两个集合。我知道我不能在 DbContext 上调用两个 ToListAsync() 方法,所以我想使用任务。
我编写了异步方法LoadData(),它应该等待完成LoadNotifications(),然后调用LoadCustomers()。
但是当执行到await this.context.MailingDeliveryNotifications.ToListAsync(); 时,它会创建另一个任务,并且不知何故它不关心我的LoadData() 方法中的task.Wait(),因此它在完成对DbContext 的第一次调用之前调用LoadCustomers()。
代码:
public async void LoadData()
{
Task task = this.LoadNotifications();
task.Wait();
await this.LoadCustomers();
}
private Task LoadNotifications()
{
return Task.Run(() => this.LoadNotificationsAsync());
}
private async void LoadNotificationsAsync()
{
List<MailingDeliveryNotification> res = await this.context.MailingDeliveryNotifications.ToListAsync();
this.Notifications = new ObservableCollection<MailingDeliveryNotification>(res);
}
private Task LoadCustomers()
{
return Task.Run(() => this.LoadNotificationsAsync());
}
private async void LoadCustomersAsync()
{
List<Customer> res = await this.context.Customers.ToListAsync();
this.Customers = new ObservableCollection<Customer>(res);
}
我知道我可以使用此代码解决此问题
public async void LoadData()
{
List<MailingDeliveryNotification> res = await this.context.MailingDeliveryNotifications.ToListAsync();
this.Notifications = new ObservableCollection<MailingDeliveryNotification>(res);
List<Customer> res2 = await this.context.Customers.ToListAsync();
this.Customers = new ObservableCollection<Customer>(res2);
}
但是当我需要添加另一个集合以从 db 加载时,这种方法会增长很多。我想保持我的代码干净。
【问题讨论】:
-
另外,
async void方法很淘气。 -
不要使用
Task.Run只是为了调用异步方法。不需要,该方法已经返回一个任务并且它已经在后台运行。 -
除了事件处理程序外,不要使用
async void。你不能等待他们,期间。async void LoadNotificationsAsync()和async void LoadData都不能等待。
标签: c# wpf entity-framework nested async-await