调用Task.Result时发生ThreadAbortException [英] ThreadAbortException when calling Task.Result

查看:70
本文介绍了调用Task.Result时发生ThreadAbortException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 HttpClient 向远程端点发出请求时使用以下代码:

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;
   }
 }

..并且有时我会在 readResponseTask.Result 上获得 ThreadAbortException ,像这样:

..and occassionally I would get ThreadAbortException at the readResponseTask.Result like so:

System.Threading.ThreadAbortException:线程正在中止.在System.Threading.Monitor.ObjWait(布尔值exitContext,Int32millisecondsTimeout,对象obj)在System.Threading.ManualResetEventSlim.Wait(Int32毫秒超时,的CancellationToken cancelToken()System.Threading.Tasks.Task.SpinThenBlockingWait(Int32millisecondsTimeout,CancelationToken cancelToken),位于System.Threading.Tasks.Task.InternalWait(Int32毫秒超时,的CancellationToken cancelToken()System.Threading.Tasks.Task.Wait(Int32毫秒超时,CancellationToken cancellingToken)

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)

.Result 在什么情况下会抛出这样的异常?我曾尝试在远程端点上模拟超时,但在 .Wait()而不是 .Result 处遇到了异常.由于异常发生在 .Wait()之后,因此我假设结果已经从远程站点返回,但是在尝试访问结果时出现了某种错误.

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?

推荐答案

我将在readResponseTask.Result上获得ThreadAbortException

I would get ThreadAbortException at the readResponseTask.Result

不,你不知道.调用堆栈清楚地表明,实际上是Wait()调用产生了异常.注意跟踪中经常出现等待"一词.

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.

很难看清您的困惑.请记住,Task.Result属性获取器很小,并且在运行程序的Release版本时将被内联.因此,您永远不会无法在堆栈跟踪中看到它.

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.

也许您只需删除Wait()调用就可以领先.没必要,必要时Result属性的getter已经执行了一个等待.

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.

这篇关于调用Task.Result时发生ThreadAbortException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆