我有一个 WPF 应用程序,它通过构造函数中的方法初始化 UI 的状态。但是,它永远不会从构造函数中的 Wait();
返回。
这是我目前通过一个相当人为设计的样本所做的事情:
public class SomeViewModel
{
public ICommand AddDataCommand { get { return RelayCommand(AddDataExecute); } }
public ObservableCollection<int> UIData { /* Property with INotifyPropertyChanged */}
public SomeViewModel()
{
//Load synch. here
LoadData().Wait();
}
public async Task LoadData()
{
UIData = await Task.Run(() => SomeService.SelectAllUIData());
}
public async void AddDataExecute()
{
//Add new data item to database on separate thread to keep UI responsive
await Task.Run(() => SomeService.AddNewData(0));
//Reload data from database and update UI, has to happen after AddNewData completes
await LoadData();
}
}
我认为它挂起是因为我实际上从未返回过 Task
。但是,我不知道有什么不同的方法可以同时在构造函数和调用它的命令中异步分配 UIData。
最佳答案
如果您需要异步构造,请不要通过构造函数构造对象。使用静态工厂方法:
public class SomeViewModel
{
private SomeViewModel()
{ }
public static async Task<SomeViewModel> Create()
{
SomeViewModel model = new SomeViewModel();
await model.LoadData();
return model;
}
public async Task LoadData()
{
UIData = await Task.Run(() => SomeService.SelectAllUIData());
}
//...
}
至于为什么您的代码不起作用,您遇到了标准的 await
死锁,您在其中阻塞了一个异步操作,该阻塞阻止了在 UI 上调用延续线程,并且有两个不同的操作,每个操作都在等待另一个继续,你会遇到死锁。这就是为什么“一直异步”而不是同步阻塞异步操作很重要。
关于c# - WPF 应用程序的异步和填充数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21437566/