我们正在从Web服务下载大量数据。这是在离散调用中完成的,回复(json)中的行数从几千到大约一百万不等。这将需要几秒钟到大约90秒的时间。一晚我们大约打200个电话,某个晚上我们可能打500个电话。
接收到数据后,我将使用JSON,然后将其批量插入SQL Server。这大约比webrequest快10倍。
我试图通过将调用添加到任务列表中,然后使用Whenany等待任务完成来使webrequest并行化
但是,当我查看任务列表之后,只要完成,就没有任何任务在运行。
我的查询在“查询”列表中,我尝试将请求添加到任务列表“答复”中
List<Task<HttpResponseMessage>> Replies = new List<Task<HttpResponseMessage>>();
while (queries.Count > 0 || Replies.Count > 0)
{
while (Replies.Count < 10 && queries.Count > 0)
{
string json = queries.First();
queries.RemoveAt(0);
HttpRequestMessage rMessage = new HttpRequestMessage(HttpMethod.Post, "");
rMessage.Headers.Add("Authorization", Token);
rMessage.Content = new StringContent(json, Encoding.UTF8, "application/json");
Replies.Add(client.SendAsync(rMessage, HttpCompletionOption.ResponseHeadersRead));
}
var finished = await Task.WhenAny(Replies);
int succeeded = Replies.Where(a => a.Status == TaskStatus.RanToCompletion).Count();
int running = Replies.Where(a => a.Status == TaskStatus.Running).Count();
int waitingact = Replies.Where(a => a.Status == TaskStatus.WaitingForActivation).Count();
int waitingrun = Replies.Where(a => a.Status == TaskStatus.WaitingToRun).Count();
Console.WriteLine("Got Reply - {0} succeeded,{1} running,{2} wact,{3} wrun", succeeded, running, waitingact, waitingrun);
Replies.Remove(finished);
}
我希望WhenAny完成后至少有一个任务正在运行,但是状态为“ RanToCompletion”,而其他所有任务的状态为“ WaitingForActivation”
我试图查看列表,并在每个任务上都调用“开始”,但这是不可能的。
所有这些内容都包含在一个异步任务中,该任务在控制台应用程序中从Main调用,运行方式为
RunBlock().GetAwaiter().OnCompleted(() => { Console.WriteLine("Done"); });
如何使任务并行运行?
答案 0 :(得分:1)
我希望在WhenAny之后至少要运行一个任务 完成,但状态为“ RanToCompletion”,并且所有 其他任务的状态为“ WaitingForActivation”
您最有可能将“委派任务”与“承诺任务”混淆。
创建具有状态Created
或WaitForActivation
的代理任务(线程池任务),然后通过WaitingToRun
将其状态更改为Running
...
承诺任务(由异步/等待生成)没有状态Running
,而是从WaitForActivation
起将其状态直接更改为RanToCompletion
/ Faulted
/ { {1}}。
这些任务最有可能正在运行,只是它们的状态不同。
您可以在amazing article的Stephen Cleary中找到很好的解释。