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");