Problem
When we have one or two tasks listed, everything works great, however when we have more than one task listed, it throws an error “A task was cancelled.”
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();
}
Asked by Karthikeyan Vijayakumar
Solution #1
A TaskCanceledException is likely to be thrown for two reasons:
It was most likely a timeout, in my opinion. (You would have figured it out if there had been an express cancellation.) You can double-check by looking at the 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.
}
Answered by Todd Menier
Solution #2
The TaskHttpResponseMessage> myTask was being terminated when my console program exited since my Main() method wasn’t waiting for the task to finish before returning.
You can make the main method asynchronous and the task to be completed asynchronously.
public static async Task Main(){
Task<HttpResponseMessage> myTask = sendRequest(); // however you create the Task
HttpResponseMessage response = await myTask;
// process the response
}
Calling myTask was the answer. GetAwaiter(). In Main(), there’s a function called GetResult() (from this answer).
Answered by Ben Hutchison
Solution #3
var clientHttp = new HttpClient();
clientHttp.Timeout = TimeSpan.FromMinutes(30);
When dealing with a huge request, the strategy described above is the best. You’re perplexed by 30 minutes; it’s an arbitrary duration, and you can give any time you choose.
In other words, requests will not be delayed for 30 minutes if they receive responses sooner. The time it takes to process a request is 30 minutes. When we get the error “Task was cancelled,” or when we have a lot of data to request.
Answered by Navdeep Kapil
Solution #4
Another possibility is that the client is not anticipating the outcome. If any method on the call stack does not utilize the await keyword to wait for the call to complete, this can happen.
Answered by Manish
Solution #5
@JobaDiniz’s comment has been promoted to an answer:
Even if the code “seems OK,” don’t do the obvious and dispose of the HttpClient instance:
async Task<HttpResponseMessage> Method() {
using (var client = new HttpClient())
return client.GetAsync(request);
}
When you dispose of a HttpClient object, any HTTP requests begun by other HttpClient instances will be canceled!
The same is true in Cnew #’s RIAA syntax, but it’s a little less obvious:
async Task<HttpResponseMessage> Method() {
using var client = new HttpClient();
return client.GetAsync(request);
}
Instead, the proper way is to cache and reuse a static instance of HttpClient for your app or library:
static HttpClient client = new HttpClient();
async Task<HttpResponseMessage> Method() {
return client.GetAsync(request);
}
(The thread-safe Async() request methods are all available.)
Answered by Carl Walsh
Post is based on https://stackoverflow.com/questions/29179848/httpclient-a-task-was-cancelled