Home > Blockchain >  Task Cancellation Exception after 3rd call
Task Cancellation Exception after 3rd call

Time:06-11

I'm new here and I hope you can help me with a problem I've got. I'm trying to call some API's from Unity UWP, but every time on the third call I've got an Task Cancellation Exception, no matter what the order is of calling the api's.

Here is my piece of code:

public class DashboardManager : MonoBehaviour
{
    public TMP_Text Status;

    async Task Awake()
    {
        await GetPerformanceInfo().ConfigureAwait(false);
        await GetProductionInfo().ConfigureAwait(false);
        await GetChecklistInfo().ConfigureAwait(false);
    }


    private async Task GetChecklistInfo()
    {
        try
        {
            HttpClient httpClient = new HttpClient((HttpMessageHandler)ApiHelpers.HttpClientHandler);
            httpClient.BaseAddress = new Uri(ApiHelpers.PlantApiBaseAddress.CheckBaseUrl(true));

            var plantApiClient = new PlantApiClient(httpClient, default); // await ProgramManager.ServiceProvider.GetService<PlantApiClient>()
            var checklists = await plantApiClient.GetChecklistWidgetInfo(UserSettings.Location);

            //Status.text = "Checklist OK";
        }
        catch (LogoutException ex)
        {
            SceneManager.LoadScene("LoginScene");
        }
        catch (TaskCanceledException ex)
        {
            Status.text = "Checklist: "   ex.Message;
        }
        catch (Exception ex)
        {
            Status.text = "Checklist: "   ex.Message;
        }
    }

    public void OnClickButton(string guid)
    {
        GlobalManager.CurrentChecklistID = guid;
        SceneManager.LoadScene("ChecklistsScene");
    }

    private async Task GetPerformanceInfo()
    {
        try
        {
            HttpClient httpClient = new HttpClient((HttpMessageHandler)ApiHelpers.HttpClientHandler);
            httpClient.BaseAddress = new Uri(ApiHelpers.PlantApiBaseAddress.CheckBaseUrl(true));

            var plantApiClient = new PlantApiClient(httpClient, default); // await ProgramManager.ServiceProvider.GetService<PlantApiClient>()
            var perfInfo = await plantApiClient.GetPerformanceWidgetInfo(UserSettings.Location);

            //Status.text = "Performance OK";
        }
        catch (LogoutException ex)
        {
            SceneManager.LoadScene("LoginScene");
        }
        catch (TaskCanceledException ex)
        {
            Status.text = "Performance: "   ex.Message;
        }
        catch (Exception ex)
        {
            Status.text = "Performance: "   ex.Message;
        }
    }

    private async Task GetProductionInfo()
    {
        try
        {
            HttpClient httpClient = new HttpClient((HttpMessageHandler)ApiHelpers.HttpClientHandler);
            httpClient.BaseAddress = new Uri(ApiHelpers.PlantApiBaseAddress.CheckBaseUrl(true));

            var plantApiClient = new PlantApiClient(httpClient, default); // await ProgramManager.ServiceProvider.GetService<PlantApiClient>()
            var prodInfo = await plantApiClient.GetProductionWidgetInfo(UserSettings.Location);

            //Status.text = "Production OK";
        }
        catch (LogoutException ex)
        {
            SceneManager.LoadScene("LoginScene");
        }
        catch (TaskCanceledException ex)
        {
            Status.text = "Production: "   ex.Message;
        }
        catch (Exception ex)
        {
            Status.text = "Production: "   ex.Message;
        }
    }
}

In the Awake Task, the 3rd call always fails with an TaskCancellation Exception. If I change the order, it always fails on the third call. There is nothing wrong with the api calls, because they are working as expected. If I just call one or two, everything works fine, but when I call a 3rd one, it fails.

What's happening here, I hope somebody can help me.

CodePudding user response:

Damn, this took me 2 wasted days, just to figure out this was a bug in Unity 2020.3.11f1. I installed version 2021.2.8f1 and everything is working fine now.

CodePudding user response:

The best practice of using HttpClient is creating a single instance and using it thoughout the lifecycle.

public class DashboardManager : MonoBehaviour
{
    static HttpClient httpClient;

    async Task Awake()
    {
        if(httpClient == null)
            httpClient = new (...);
    }
}

Otherwise remember to release it when you finished.

httpClient.Dispose();

There is a connection limitation (default value 2) in .net. Though objects can be collected by GC, if you use multiple HttpClient and don't release it timely, you'll get exceptions when the limitation reaches.

  • Related