I have the following code where I'm trying to make a request to a remote endpoint using HttpClient
:
using (var client = new HttpClient())
{
client.BaseAddress = _serviceBaseAddress;
Task<HttpResponseMessage> readResponseTask = client.GetAsync(relativeUri);
readResponseTask.Wait();
using (var response = readResponseTask.Result)
{
if (response.StatusCode == HttpStatusCode.NotFound || !response.IsSuccessStatusCode)
{
return default(TResult);
}
Task<TResult> readContentTask = response.Content.ReadAsAsync<TResult>();
readContentTask.Wait();
TResult value = readContentTask.Result;
return value;
}
}
..and occassionally I would get ThreadAbortException
at the readResponseTask.Result
like so:
System.Threading.ThreadAbortException: Thread was being aborted. at System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj) at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
Under what circumstance will the .Result
throw such an exception? I have tried simulating a timeout on the remote endpoint but I got the exception at the .Wait()
instead of .Result
. Since the exception happens after .Wait()
, I'm assuming the result has already been returned from the remote site but somehow something went wrong when it tries to access the result.
Any clues? Could it be something to do with thread concurrency?
I would get ThreadAbortException at the readResponseTask.Result
No, you don't. The call stack clearly shows that it is in fact the Wait() call that produced the exception. Note the frequent appearance of the word "wait" in the trace.
Hard to see how you got confused. Keep in mind that the Task.Result property getter is very small and is going to be inlined when you run the Release build of your program. So you never can see it back in the stack trace.
Perhaps you'll be ahead by simply removing the Wait() call. It isn't necessary, the Result property getter already performs a wait if necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With