Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c#: Restart an Async task after certain time passes before completion

So, I've been working on an app that consumes REST API requests, however, for some reason, the API gets unresponsive randomly (sometimes it gives a response within 3 seconds and sometimes the request will take so long that it throws a TimeoutException) so Whenever I consume a call I use this code to restart the call if no response is retrieved during a certain amount of time:

bool taskCompletion = false;
while(taskCompletion == false)
{
    try
    {
        using (CancellationTokenSource cts = new CancellationTokenSource())
        {
            cts.CancelAfter(timeSpan);
            await task(cts.Token);
            taskCompletion = true;
        }
    }
    catch (OperationCanceledException)
    {
        taskCompletion = false;
    }
}

and one of my API requests is the following:

public static async Task<Result> task(CancellationToken ct)
{
    string Url = baseurl
    ApiHelper instance = new ApiHelper();

    using (HttpResponseMessage response = await instance.ApiClient.GetAsync(Url, ct))
    {
        if (response.IsSuccessStatusCode)
        {
            var x = await response.Content.ReadAsStringAsync();
            var result = JsonConvert.DeserializeObject<ResultL>(x);
            if (result.result.Count() != 0)
                return result.result[0];
            else
                return null;
        }
        return null;
    }
}

I don't think however that using the try-catch every time for each of the different API requests the code consumes is the best solution, any help on how to improve my code will be highly appreciated!

like image 458
callencx Avatar asked May 27 '20 15:05

callencx


1 Answers

Have you considered using a fault-resilience library? One example for .net is Polly. https://github.com/App-vNext/Polly

This is helpful because you can easily configure the retry count or the timeout as well as fallback logic for certain type of exceptions.

There is also a very helpful article by Scott Hanselman on this: https://www.hanselman.com/blog/AddingResilienceAndTransientFaultHandlingToYourNETCoreHttpClientWithPolly.aspx

I have used it before and it made my code super clean and easy to manage, since all policies are in one place, and not part of the http response handler. You can also have a separate policy for each different http requestor or client if needed.

like image 137
mehtarit Avatar answered Nov 04 '22 16:11

mehtarit