应用程序挂起等待异步方法 [英] Application hangs on wait async method
问题描述
我的页面上有两个组合框控件,它们绑定到ObservableCollection< Vendor>.和ObservableCollection< Driver>.
I've got two combobox controls on my page, binded to a ObservableCollection<Vendor> and ObservableCollection<Driver>.
加载页面后,将执行OnWindowLoaded(). 触发属性Vendor的设置器后,将执行OnVendorPropertyChanged. 当OnWindowLoaded()完成时,将正确设置供应商和驱动程序.
When the page is loaded the OnWindowLoaded() is executed. When the setter of the property Vendor is triggered, OnVendorPropertyChanged is executed. When OnWindowLoaded() finishes, Vendor and Driver is being set correctly.
但是,当我更改供应商时,应用程序会在线等待
However when I change the Vendor, the application waits on the line
LoadDriversAsync(Vendor.DCP).Wait();
我该如何解决?
private async void OnWindowLoaded()
{
Debug.WriteLine("Enter OnWindowLoaded");
await LoadVendorsAsync();
await System.Threading.Tasks.Task.Run(() => { Vendor = Vendors.FirstOrDefault(); });
await System.Threading.Tasks.Task.Run(() => { Driver = Drivers.FirstOrDefault(); });
Debug.WriteLine("Leave OnWindowLoaded");
}
private Vendor _vendor;
public Vendor Vendor
{
get
{
return _vendor;
}
set
{
if (value != _vendor)
{
var oldVendor = new Vendor();
oldVendor = _vendor;
_vendor = value;
RaisePropertyChanged(nameof(Vendor), oldVendor, Vendor, true);
}
}
}
/// <summary>
/// Raised when Vendor property is changed
/// </summary>
/// <param name="vendor"></param>
private void OnVendorPropertyChanged(PropertyChangedMessage<Vendor> vendor)
{
Debug.WriteLine("Enter OnVendorPropertyChanged");
//application hangs when vendor is changed
LoadDriversAsync(Vendor.DCP).Wait();
Debug.WriteLine("Leave OnVendorPropertyChanged");
}
private async System.Threading.Tasks.Task LoadVendorsAsync()
{
Debug.WriteLine("Enter LoadVendorsAsync");
//load the vendors, don't return data
Debug.WriteLine("Leave LoadVendorsAsync");
}
private Vendor _vendor;
public Vendor Vendor
{
get
{
return _vendor;
}
set
{
if (value != _vendor)
{
var oldVendor = new Vendor();
oldVendor = _vendor;
_vendor = value;
RaisePropertyChanged(nameof(Vendor), oldVendor, Vendor, true);
}
}
}
ObservableCollection<Vendor> _vendors = new ObservableCollection<Vendor>();
public ObservableCollection<Vendor> Vendors
{
get
{
return _vendors;
}
set
{
if (_vendors != value)
{
var oldVendors = _vendors;
_vendors = value;
RaisePropertyChanged(nameof(Vendors), oldVendors, Vendors, true);
}
}
}
private async System.Threading.Tasks.Tas LoadDriversAsync(Objects.Vendor Vendor)
{
Debug.WriteLine("Enter LoadDriversAsync");
//load data, don't return
Debug.WriteLine("Leave LoadDriversAsync");
RaisePropertyChanged(nameof(Drivers), oldDrivers, Drivers, true);
}
}
输出
Enter OnWindowLoaded
Enter LoadVendorsAsync
Leave LoadVendorsAsync
Enter OnVendorPropertyChanged
Enter LoadDriversAsync
Leave LoadDriversAsync
Leave OnVendorPropertyChanged
Leave OnWindowLoaded
已编辑
遵循Boo的建议无济于事.更改供应商时,应用程序仍会阻止.
Following Boo advice did not help. Application still blocks when changing vendor.
遵循@Frederik Gheysels的建议无济于事.
Following @Frederik Gheysels advice did not help.
输出
Enter OnWindowLoaded
Enter LoadVendorsAsync
Enter OnVendorPropertyChanged
Enter LoadDriversAsync
Leave OnWindowLoaded
Leave LoadDriversAsync
Leave OnVendorPropertyChanged
推荐答案
拥有异步方法后,您几乎再也不想调用wait.
You will almost never want to call wait when you have async methods.
这是一个死锁如何发生的示例
Here is an example how deadlock can happen
- 称为异步方法
- 异步方法进入等待状态,主线程运行其他内容
- 主线程执行一个调用wait()的方法
- wait正在等待异步完成
- 异步正在等待主线程变为空闲状态
- 死亡锁
因此,如果可能的话,将您调用.wait()的方法更改为异步并对其调用await
so if it is possible, change the method where you are calling .wait() on to be async and call await on it
这篇关于应用程序挂起等待异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!