Home > Software design >  Get HttpClient to abort the connection
Get HttpClient to abort the connection

Time:09-23

Background (ignorable)

I am trying to re-create a bug situation on my development machine, described in this github issue: https://github.com/dotnet/aspnetcore/issues/28568. The actual bug I am seeing is when my application runs in Kubernetes. The details of that bug are documented here: Handling Errors in Health Checks

Problem

I am trying to get an HttpClient to abort a connection, to hopefully cause a System.Threading.Tasks.TaskCanceledException in my ASP.Net Core WebAPI Service. The text I am working off (found in the GitHub issue linked above) says that my issue happens:

when the client disconnect[s] before the request has been completely processed and is caused by the HttpContext.RequestAborted cancellation token.

I need to recreate this issue on my development machine. To do that I have created a console application with an HttpClient that calls my service endpoint. I have tried two different ways to recreate this so far. First I call:

var sendTask = httpClient.SendAsync(message, cancellationTokenSource.Token);

Then, in the first attempt I called:

cancellationTokenSource.Cancel();

In the second attempt, I took out the call to Cancel and put in this:

httpClient.Dispose();

I put the logic in a loop and ran it a bunch of times, but I was unable to reproduce the exception I am looking for (TaskCanceledException) in the service (confusingly it is thrown in the client when Cancel is called).

Is there a way to case the HttpClient to disconnect before the call is done?

CodePudding user response:

I realized that I had not been resetting my CancellationTokenSource after I called Cancel. Once I did that, about 1 in 20ish calls started throwing the TaskCanceledException in my service.

Just incase others want it (and for later reference), here is the code that I used to generate the error:

var url = "https://localhost:7249/health/liveness";
var httpClient = new HttpClient();
for (int loopIndex = 0; loopIndex < 1000; loopIndex  )
{
    try
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        var message = new HttpRequestMessage(HttpMethod.Get, url);
        // Important: don't await this or it will cause the call to finish before continuing.
        httpClient.SendAsync(message, cancellationTokenSource.Token);
        cancellationTokenSource.Cancel();
    }
    catch (Exception e) { }

    Console.WriteLine($"Next {loopIndex}");
}

Console.WriteLine("All Done");
  • Related