Reputation: 31546
I saw couple of posts on this... but most people are manually creating tasks rather than receiving it from an API.
I have this code
Task[] tasks = new Task[companyCount];
// start all threads
for(int i = 0; i < companyCount; i++) {
string input = GetNextCompanyRecord(i);
string token = GetUserToken();
HttpClient client = GetHttpClient();
StringContent content = CreateStringContent(input);
var x = client.PostAsync(companyUrlString, content).ConfigureAwait(continueOnCapturedContext: false);
tasks[i] = x;
}
Task.WaitAll(tasks);
the objective is that I start the task for each record in a for loop and then when all tasks are started ... doing a single waitall.
problem is that I cannot assign the x variable to the task array.
The PostAsync method is not returning me the Task. instead it is returning ConfiguredTaskAwaitable. But my hope was that I will get Task and I will be able to add that to my array and then do a waitall.
Upvotes: 0
Views: 1516
Reputation: 117027
Just do it like this:
Task<HttpResponseMessage>[] tasks = new Task<HttpResponseMessage>[companyCount];
for(int i = 0; i < companyCount; i++)
{
string input = GetNextCompanyRecord(i);
string token = GetUserToken();
HttpClient client = GetHttpClient();
StringContent content = CreateStringContent(input);
var x = client.PostAsync(companyUrlString, content);
tasks[i] = x;
}
Task.WaitAll(tasks);
But, perhaps a cleaner way would be to do this:
var tasks =
from i in Enumerable.Range(0, companyCount)
let input = GetNextCompanyRecord(i)
let token = GetUserToken()
let client = GetHttpClient()
let content = CreateStringContent(input)
select client.PostAsync(companyUrlString, content);
Task.WaitAll(tasks.ToArray());
Or even better yet:
using (var client = GetHttpClient())
{
var tasks =
from i in Enumerable.Range(0, companyCount)
let input = GetNextCompanyRecord(i)
let token = GetUserToken()
let content = CreateStringContent(input)
select client.PostAsync(companyUrlString, content);
Task.WaitAll(tasks.ToArray());
}
Upvotes: 6
Reputation: 68640
PostAsync
is returning a Task
(a Task<HttpResponseMessage>
, to be precise), but then you're calling ConfigureAwait
on it, which returns a ConfiguredTaskAwaitable
.
Try getting a reference to the task first, and then calling ConfigureAwait
.
var task = client.PostAsync(companyUrlString, content);
ConfiguredTaskAwaitable awaitable = task.ConfigureAwait(continueOnCapturedContext: false);
tasks[i] = task;
Also, consider:
ConfigureAwait
, since you don't seem to need it anyway.Task[]
to Task<HttpResponseMessage>[]
, if you want to retrieve the tasks' results when they're done.Upvotes: 3