How to Wait for Async Method to Complete

How to wait for async method to complete?

Avoid async void. Have your methods return Task instead of void. Then you can await them.

Like this:

private async Task RequestToSendOutputReport(List<byte[]> byteArrays)
{
foreach (byte[] b in byteArrays)
{
while (condition)
{
// we'll typically execute this code many times until the condition is no longer met
Task t = SendOutputReportViaInterruptTransfer();
await t;
}

// read some data from device; we need to wait for this to return
await RequestToGetInputReport();
}
}

private async Task RequestToGetInputReport()
{
// lots of code prior to this
int bytesRead = await GetInputReportViaInterruptTransfer();
}

C# Wait for async method to finish before continuing

Now how can I await the LoadTemplateList()?

With the await keyword:

handling = true;

await LoadTemplateList();

handling = false;

However, it will still return early, because the code is doing some funky private EventHandler stuff. If you just remove all that excess code and move the asynchronous code into LoadTemplateList, it will work fine:

public class TemplateListViewModel
{
public double WidthHeight { get; set; }

public ICommand LoadTemplates => new Command(MyHandler);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }

public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();

var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;

WidthHeight = (ScaledWidth / 2);

MyHandler();
}

private async Task LoadTemplateList()
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);

if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}

CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}

bool handling = false;

public async void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;

handling = true;

await LoadTemplateList();

handling = false;
}
}

How to wait for async void to complete?

Return Task (not Task<T>) instead of void. Note, the non-generic form of Task does not need to wrap a value. It's just for signalling completion or errors, not results. In the case of async methods, this is equivalent to a synchronous void return type. It means you can wait for your method to complete.

how to wait for await in async method to finish the all the executions?

If you need LoadSystemDetails to wait for GetAllFields, there are 2 problems here:

  • you are calling async method from a synchronous context
  • GetAllFields is async void, which means fire and forget. You will never be able to wait for it to finish.

Solution:
First, NEVER use async void if you need to wait for the result or end. Use async Task instead

Second, either convert LoadSystemDetails to async method also, then await the GetAllFields (that should return Task), or use GetAllFields(clientId).Wait()

take a look at this article for more information on async/await: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Xamarin Forms - Wait for async method to complete before continuing

The Task.Wait() and Task.Result will make the program wait for the async task method competed.

If the CloseCurOpenJob() is like public async Task<bool> CloseCurOpenJob(){} You can try the following code:

// Both are applicable to simple Tasks:
bool jobTask = CloseCurOpenJob().Result;

or

Task<bool> result = CloseCurOpenJob();
result.Wait();
bool jobTask = result.Result;

According to your description, you want update the popup when it show. But you sayed that the popup will not show when you used the .Wait() method.

Generally speaking, it shouldn't happen. But you can try to use the Thread.Sleep() such as:

bool jobTask = await CloseCurOpenJob();
Thread.Sleep(1000); //make the thread to wait for 1s and the async task usually completes in 1s
if (jobTask == true)
{
await FillDocuments();
}

But this way seems not elegant, you can post the code about the CloseCurOpenJob() method. In addition, if the CloseCurOpenJob() is public async bool CloseCurOpenJob(), you can make the thread wait without the await. Such as

bool jobTask = CloseCurOpenJob();


Related Topics



Leave a reply



Submit