异步方法不等待

在这个线程中 ,我可以解决我的问题,在构造函数中使用事件等待异步方法。 在这种情况下,事件使用不带参数的委托。

但是现在我需要等待视图模型完成等待异步方法才能继续。

我在主视图模型中有这个代码:

public void printMethod() { SecondViewModel mySeocViewModel = new SecondViewModel(myParameter); SecondView mySecondView = new SecondView(); mySecondView.DataContext = mySeocViewModel; //I have to wait until it finished to can print the user control //The problem is that this point is reached before mySecondViewModel finish. } 

我的第二个视图模型中的代码:

 public docFacturasViewModel(MyType parameter) { this.GetDataFromDatabaseEvent += OnGetDataFromDatabase; GetDataFromDatabaseEvent(parameter); } public delegate void GetDataFromDatabaseEventHandler(MyType parameter); public event GetDataFromDatabaseEventHandler GetDataFromDataBaseEvent; private async void OnBuscarDatos(MyType paramter) { await getDataFromDatabaseAsync(parameter); //Fill the data of the properties of the view model with the data from database } private async Task getDataFromDatabaseAsync(MyType parameter) { _myResult = (await getdataAsync(parameter)).FirstOrDefault(); } 

如果我调试代码,它以这种方式运行:

  • 它到达主视图模型中的线以创建第二个视图模型。
  • 在第二个视图模型中,它到达OnGetDataFromDatabase方法的第一行,即await。
  • 主视图模型继续使用代码,因此它不会等待数据库的结果。
  • 过了一段时间,在第二个视图模型中,方法OnGetDataFromDatabase会在await之后继续下一行代码。

我不明白为什么在第二个视图模型中代码不等到从数据库中获取数据,因为我使用的是await关键字,并且所有代码都与我链接的post的情况相同开始。

谢谢。

编辑:

如果我使用第二个视图模型的构造函数:

 Task.Run(() => buscarDatosAsync(paramFacturaParaImprimir)).Wait(); 

然后主视图模型等到第二个视图模型完成以从数据库获取数据。

但是当我在第一种情况下尝试这种方法时,在我链接的情况下,我在另一篇文章中询问,该方法没有等待,所以我不明白为什么在一种情况下我必须使用委托并且在其他情况我可以使用任务并等待它完成。

async void方法到达await ,控件将返回给调用者。 显然,当您需要操作结果继续处理时,这不是最好的主意。 除此之外,我不希望构造函数具有创建“即发即弃”任务的副作用。

如果您需要将数据结果作为对象构造的一部分,我建议您采用工厂方法:

 private SecondViewModel() { } public static async Task CreateAsync(MyType parameter) { var result = new SecondViewModel(); result.SomeData = await getDataFromDatabaseAsync(parameter); return result; } 

你会像这样使用它:

 public async Task printMethod() { SecondViewModel mySeocViewModel = await SecondViewModel.CreateAsync(myParameter); SecondView mySecondView = new SecondView(); mySecondView.DataContext = mySeocViewModel; } 

假设您正在编写一些基于XAML的代码,那么您在这里遇到了设计问题。

不要混合视图模型创建和数据加载。 通常,您可以同步创建视图模型和视图,并以异步方式加载/发布数据。 所以,不要在视图模型构造函数中等待任何内容。

视图模型和视图必须在没有任何数据的情况下正常运行(当数据属性为null或空集合时)。 如果您不想在加载数据之前授予对某些命令的访问权限,请禁用这些命令(从CanExecute返回false )。