HttpClient – 任务被取消了?
当有一个或两个任务,但是当我们有多个任务列出的时候会抛出一个错误“一个任务被取消”。
List<Task> allTasks = new List<Task>(); allTasks.Add(....); allTasks.Add(....); Task.WaitAll(allTasks.ToArray(), configuration.CancellationToken); private static Task<T> HttpClientSendAsync<T>(string url, object data, HttpMethod method, string contentType, CancellationToken token) { HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url); HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(Constants.TimeOut); if (data != null) { byte[] byteArray = Encoding.ASCII.GetBytes(Helper.ToJSON(data)); MemoryStream memoryStream = new MemoryStream(byteArray); httpRequestMessage.Content = new StringContent(new StreamReader(memoryStream).ReadToEnd(), Encoding.UTF8, contentType); } return httpClient.SendAsync(httpRequestMessage).ContinueWith(task => { var response = task.Result; return response.Content.ReadAsStringAsync().ContinueWith(stringTask => { var json = stringTask.Result; return Helper.FromJSON<T>(json); }); }).Unwrap(); }
有2个可能的原因会引发TaskCanceledException
:
- 在任务完成之前,与取消标记关联的
CancellationTokenSource
上的Cancel()
。 - 请求超时,即在您在
HttpClient.Timeout
指定的时间范围内没有完成。
我的猜测是这是一个超时。 (如果这是一个明确的取消,你可能会想出来。)通过检查exception,你可以更确定:
try { var response = task.Result; } catch (TaskCanceledException ex) { // Check ex.CancellationToken.IsCancellationRequested here. // If false, it's pretty safe to assume it was a timeout. }
我遇到了这个问题,因为我的Main()
方法没有等待任务完成,所以Task<HttpResponseMessage> myTask
在退出控制台程序时被取消。
解决的办法是在Main()
调用myTask.GetAwaiter().GetResult()
Main()
(从这个答案 )。
另一种可能性是结果不在客户端等待。 如果调用堆栈中的任何一个方法不使用await关键字来等待调用完成,就会发生这种情况。