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
How to Disable a System Device Programmatically
How to Name Variables Dynamically in C#
Notify Binding for Static Properties in Static Classes
Identityserver4 Register Userservice and Get Users from Database in ASP.NET Core
How to Get the Index of an Item in a List in a Single Step
Databind the Source Property of the Webbrowser in Wpf
How to Convert Datetime To/From Specific String Format (Both Ways, E.G. Given Format Is "Yyyymmdd")
Can't Get SQL Server Compact 3.5/4 to Work with Asp .Net MVC 2
I Didn't Find "Zipfile" Class in the "System.Io.Compression" Namespace
Accessing UI Control from Backgroundworker Thread
C#: Prepending to Beginning of a File
How to Wait for Async Method to Complete
Upload Files and JSON in ASP.NET Core Web API