I know there are several posts about this before:
[https://stackoverflow.com/questions/15149811/how-to-wait-for-async-method-to-complete][1]
[https://stackoverflow.com/questions/13636648/wait-for-a-void-async-method][2]
I have not got any of this to work.
In my Winform application the queries to the database is only accessible through async methods.
I need the list myObjectsList to be populated with the result before I call the method:
DisplayInTheDatagridview(myObjectsList).
Now this method is always called with an empty list.
If I set a breakpoint in my code and wait the result will be finished,
so the database has the actual data I want to retrieve.
This is what I have tried so far:
public void ShowRowsInDatagridview(List<MyObjects> listRowsToQueryDB)
{
List<MyObjects> myObjectsList = new List<MyObjects>();
var task = client.GetListFromDBAsync(listRowsToQueryDB);
task.Wait();
var result = task.Result;
myObjectsList = (List<MyObjects>)result;
DisplayInTheDatagridview(myObjectsList);
}
public void ShowRowsInDatagridview(List<MyObjects> listRowsToQueryDB)
{
List<MyObjects> myObjectsList = new List<MyObjects>();
var result = client.GetListFromDBAsync(listRowsToQueryDB).GetAwaiter().GetResult();
myObjectsList = (List<MyObjects>)result;
DisplayInTheDatagridview(myObjectsList);
}
public void ShowRowsInDatagridview(List<MyObjects> listRowsToQueryDB)
{
List<MyObjects> myObjectsList = new List<MyObjects>();
var result = Task.Run(async () => await client.GetListFromDBAsync(listRowsToQueryDB)).Result;
myObjectsList = (List<MyObjects>)result;
DisplayInTheDatagridview(myObjectsList);
}
>Solution :
The typical solution is to use await
public async Task ShowRowsInDatagridview(List<MyObjects> listRowsToQueryDB)
{
var result = await client.GetListFromDBAsync(listRowsToQueryDB);
var myObjectsList = (List<MyObjects>)result;
DisplayInTheDatagridview(myObjectsList);
}
This achieves the objective of running DisplayInTheDatagridview after the database call has completed, while letting the UI thread be free to do other stuff while the db call completes. This assumes your database is actually async, and are not just faking it.
Make sure to await ShowRowsInDatagridview from whenever it is called, and make sure that method also returns a task. If you reach an event handler where you cannot return a task you should make the method async void, but make sure to catch and handle any exceptions that occur while calling the database.
If you want to block the UI while the db call is in progress you can do things like disable buttons until the call completes, or show a modal dialog to prevent the UI from being used.