George M Ceaser Jr
George M Ceaser Jr

Reputation: 1781

Cannot get Task.WaitAll to work

I am trying to get Task.WaitAll to work but my code never gets past the WaitAll line of code. It is pretty simple. On Appearing event of the main page tries to make a couple of calls to Web APIs. Any suggestions / ideas as to what I am doing wrong?

Below is the code in the OnAppearing event of my page

   protected override void OnAppearing()
    {
        try
        {
            base.OnAppearing();
            List<Task<String>> lobj_TaskList = new List<Task<String>>();
            WebAPICaller lobj_WebAPICaller = new WebAPICaller();
            Debug.WriteLine("Process StartUp");

            lobj_TaskList.Add(lobj_WebAPICaller.HTTPGetWebServiceAsync("/DOW/EN"));
            lobj_TaskList.Add(lobj_WebAPICaller.HTTPGetWebServiceAsync("/languages/true"));

            Task.WaitAll(lobj_TaskList.ToArray());
        }
        catch (Exception ex)
        {
            App.ProcessException(ex);
        }
    }

Here is the WebAPICaller Class

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace TestWebAPI
{
public class WebAPICaller : IDisposable

{
    HttpClient iobj_HTTPClient = null;
    public void Dispose()
    {
        if (iobj_HTTPClient != null)
            iobj_HTTPClient.Dispose();

    }

    public async Task<string> HTTPGetWebServiceAsync(string ps_URI)
    {

        string ls_Response = "";
        string ls_JSONData = "";
        string ls_Prefix = "";

        try
        {
            iobj_HTTPClient = await GetClient();

            switch (Device.RuntimePlatform)
            {
                case Device.Android:
                    ls_Prefix = App.APIStandardPrefix;
                    break;
                default:
                    ls_Prefix = App.APISecurePrefix;
                    break;
            }

            Debug.WriteLine("before api call");
            iobj_HTTPClient.BaseAddress = new Uri(ls_Prefix);
            ls_JSONData = await iobj_HTTPClient.GetStringAsync(ps_URI);
            Debug.WriteLine("after api call");
            ls_Response = System.Net.WebUtility.HtmlDecode(ls_JSONData);

        }
        catch (Exception ex)
        {
            Debug.WriteLine("api call error");
            App.ProcessException(ex);
        }
        return ls_Response;

    } 

    private async Task<HttpClient> GetClient()
    {
        HttpClient lobj_HTTPClient = null;

        if (lobj_HTTPClient == null)
        {
            lobj_HTTPClient = new HttpClient();
            lobj_HTTPClient.DefaultRequestHeaders.Add("Accept", "application/json");
            lobj_HTTPClient.MaxResponseContentBufferSize = 2147483647;
            lobj_HTTPClient.Timeout = new TimeSpan(0, 0, 0, 0, 60000);
        }

        return lobj_HTTPClient;
    }

}
}

Upvotes: 1

Views: 605

Answers (1)

Pavan V Parekh
Pavan V Parekh

Reputation: 1946

Use Task.WhenAll instead of Task.WaitAll,

WhenAll will wait for all tasks to complete. A chain of await would abort waiting at the first exception but the execution of non-awaited tasks continues. This causes unexpected concurrency.

Have a look below code, It will help you.

protected async override void OnAppearing()
{
    try
    {
        base.OnAppearing();
        List<Task<String>> lobj_TaskList = new List<Task<String>>();
        WebAPICaller lobj_WebAPICaller = new WebAPICaller();
        Debug.WriteLine("Process StartUp");

        lobj_TaskList.Add(lobj_WebAPICaller.HTTPGetWebServiceAsync("/DOW/EN"));
        lobj_TaskList.Add(lobj_WebAPICaller.HTTPGetWebServiceAsync("/languages/true"));

        await Task.WhenAll(lobj_TaskList.ToArray());
    }
    catch (Exception ex)
    {
        App.ProcessException(ex);
    }
}

Upvotes: 2

Related Questions