简体   繁体   English

异步方法不是等待

[英]The async method is not await

In this thread , I could solve my problem to wait a async method in the constructor, using an event. 在这个线程中,我可以解决我的问题,使用事件在构造函数中等待异步方法。 In this case, the event uses a delegate without parameters.在这种情况下,事件使用不带参数的委托。

But now I need to wait the view model finishes to wait the async method to can continue.但是现在我需要等待视图模型完成以等待异步方法可以继续。

I have this code in my main view model:我的主视图模型中有此代码:

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.
}

The code in my second view model:我的第二个视图模型中的代码:

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();
}

If i debug the code, it runs in this way:如果我调试代码,它会以这种方式运行:

  • It reaches the line in the main view model to create the second view model.它到达主视图模型中的行以创建第二个视图模型。
  • In the second view model, it reaches the line in the method OnGetDataFromDatabase the first line, the await.在第二个视图模型中,它到达方法 OnGetDataFromDatabase 中的第一行,即等待。
  • The main view model continue with the code, so it doesn't wait the result from database.主视图模型继续执行代码,因此它不会等待来自数据库的结果。
  • After a time, in the second view model, the method OnGetDataFromDatabase fnish and continue with the next line of code after the await.一段时间后,在第二个视图模型中,方法 OnGetDataFromDatabase 完成并继续等待后的下一行代码。

I don't understand why in the second view model the code doesn't wait until get the data from the database, because I am using the await keyword and all the code is the same than in the case of the post that I link at the beggining.我不明白为什么在第二个视图模型中代码不等到从数据库中获取数据,因为我使用的是 await 关键字并且所有代码与我链接的帖子的情况相同开始。

Thanks.谢谢。

EDIT:编辑:

If the constructor of the second view model I use this:如果我使用第二个视图模型的构造函数:

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

Then the main view model wait until the second view model finish to get the data from database.然后主视图模型等待第二个视图模型完成从数据库中获取数据。

But when I tried this method in the first case, in the case that I linked and I asked in the other post, the method is not waited, so I don't understand why in one case I have to use a delegate and in the other case I can use a task and wait it finishes.但是当我在第一种情况下尝试这种方法时,在我链接并在另一篇文章中询问的情况下,该方法没有等待,所以我不明白为什么在一种情况下我必须使用委托,而在其他情况我可以使用任务并等待它完成。

When an async void method reaches an await , the control is returned to the caller.async void方法到达await ,控制权返回给调用者。 Obviously, this is not the best idea when you need the result of the operation to continue processing.显然,当您需要操作的结果来继续处理时,这不是最好的主意。 Besides this, I wouldn't expect a constructor to have the side effect of creating fire-and-forget tasks.除此之外,我不希望构造函数具有创建即发即忘任务的副作用。

If you need the result of the data as part of the construction of the object, I would suggest you a factory approach:如果您需要数据的结果作为对象构造的一部分,我建议您采用工厂方法:

private SecondViewModel()
{
}

public static async Task<SecondViewModel> CreateAsync(MyType parameter)
{
    var result = new SecondViewModel();

    result.SomeData = await getDataFromDatabaseAsync(parameter);

    return result;
}

And you would use it like this:你会像这样使用它:

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

Assuming, that you're writing some XAML-based code, you've got a design problem here.假设您正在编写一些基于 XAML 的代码,那么这里存在设计问题。

Do not mix view model creation and data loading.不要混合视图模型创建和数据加载。 Usually you create view models and views synchronously, and load/post data in asynchronous way.通常你同步创建视图模型和视图,并以异步方式加载/发布数据。 So, don't wait anything inside view model constructors.所以,不要在视图模型构造函数中等待任何东西。

View models and views must operate properly without any data (when data properties are null s or empty collections).视图模型和视图必须在没有任何数据的情况下正常运行(当数据属性为null或空集合时)。 If you don't want to give access to some of commands until data is loaded, just disable these commands (return false from CanExecute ).如果您不想在加载数据之前访问某些命令,只需禁用这些命令(从CanExecute返回false )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM