Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c# - 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.
  • 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.

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When an async void method reaches an await, the control is returned to the caller. 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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...