我看到了几个帖子......但是大多数人都在手动创建任务而不是从API接收任务。
我有这段代码
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);
目标是我为for循环中的每条记录启动任务,然后在所有任务开始时......执行一次waitall。
问题是我无法将x变量分配给任务数组。
PostAsync方法没有给我返回任务。相反,它返回ConfiguredTaskAwaitable。但我的希望是我将获得Task,我将能够将其添加到我的阵列中,然后再进行等待。
答案 0 :(得分:5)
就这样做:
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);
但是,也许更清洁的方法是这样做:
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());
甚至更好:
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());
}
答案 1 :(得分:3)
PostAsync
返回Task
(确切地说是一个Task<HttpResponseMessage>
),但之后您正在调用ConfigureAwait
它,返回ConfiguredTaskAwaitable
。
首先尝试获取对任务的引用,然后调用ConfigureAwait
。
var task = client.PostAsync(companyUrlString, content);
ConfiguredTaskAwaitable awaitable = task.ConfigureAwait(continueOnCapturedContext: false);
tasks[i] = task;
另外,请考虑:
ConfigureAwait
的通话,因为您似乎无论如何都不需要它。Task[]
更改为Task<HttpResponseMessage>[]
。他们完成后的结果。