如果 Task<HttpResponseMessage>.IsCompleted 为真,为啥 Task<HttpResponseMessage>.Result 会抛出异常?

Posted

技术标签:

【中文标题】如果 Task<HttpResponseMessage>.IsCompleted 为真,为啥 Task<HttpResponseMessage>.Result 会抛出异常?【英文标题】:Why does Task<HttpResponseMessage>.Result throw an exception if Task<HttpResponseMessage>.IsCompleted is true?如果 Task<HttpResponseMessage>.IsCompleted 为真,为什么 Task<HttpResponseMessage>.Result 会抛出异常? 【发布时间】:2020-08-10 07:34:18 【问题描述】:

这只发生在重负载下,所以我不能举一个简单的例子。这是一个系统测试,所以我试图避免等待,而是创建 2,000 个请求,然后轮询响应何时完成。

有问题的代码是:

Task<HttpResponseMessage> response = responseStatus.Item1;
if (!response.IsCompleted)
    continue;
HttpResponseMessage result = response.Result;

对 Result 的调用会引发以下情况:

System.AggregateException: One or more errors occurred.
StackTrace:       at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at SystemTests.V2.LoadTests.Test1000Requests() in C:\git\Jenova\restfulengine\SystemTests.V2\LoadTests.cs:line 121
INNER EXCEPTION:    System.Threading.Tasks.TaskCanceledException: A task was canceled.
StackTrace:    System.AggregateException: One or more errors occurred. ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at SystemTests.V2.LoadTests.Test1000Requests() in C:\git\Jenova\restfulengine\SystemTests.V2\LoadTests.cs:line 121
---> (Inner Exception #0) System.Threading.Tasks.TaskCanceledException: A task was canceled.<---

2020-04-26 13:36:06,370 [MSTestAdapter Thread] WARN SystemTests.V2.LoadTests - v2/reports/19ea788d-ceb8-4a81-a974-f597494609dd failed (will retry)System.AggregateException: One or more errors occurred. ---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at SystemTests.V2.LoadTests.Test1000Requests() in C:\git\Jenova\restfulengine\SystemTests.V2\LoadTests.cs:line 121
---> (Inner Exception #0) System.Threading.Tasks.TaskCanceledException: A task was canceled.<---

【问题讨论】:

【参考方案1】:

Task.IsCompleted 为“如果任务已完成,则为 true(即,任务处于三种最终状态之一:RanToCompletion、Faulted 或 Canceled);否则为 false。”

因此,如果 HTTP 请求以无法创建可用HttpResponseMessage 的方式失败,您将无法访问结果。所以检查 Task.Status 看看它是什么。

【讨论】:

就是这样。我认为 IsCompleted 意味着成功。是的 - 我应该仔细阅读文档。 @DavidThielen 没错。在 .NET Core 中,他们添加了属性 IsCompletedSuccessfully。不幸的是,这个有用的属性在 .NET Framework 中不可用(并且可能永远不会)。

以上是关于如果 Task<HttpResponseMessage>.IsCompleted 为真,为啥 Task<HttpResponseMessage>.Result 会抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

task

异步接口

Java线程池ThreadPoolExecuter:execute()原理

UVa 11728 Alternate Task

C#5 异步返回类型 - 澄清?

关于单片机实时系统的问题KEIL中的rtx51tny