我有以下代码:
List<Task<int>> taskArray = new List<Task<int>>();
for (int i = 0; i < 100; i++)
{
taskArray.Add(myCrawler.getWebPageCharsCount("https://www.something.com"));
}
方法如下:
public Task<int> getWebPageCharCount(string url)
{
var client = new HttpClient();
return Task.Run(async () =>
{
Task<string> task = client.GetStringAsync(url);
string taskResult = await task;
return taskResult.Length;
});
}
在此之后,有100个线程正在运行,我想要实现的是在每个单独的任务完成后处理主线程中的结果,而不是等待所有结果,这将使用以下代码:< / p>
var results = await Task.WhenAll(taskArray);
foreach (var res in results)
{
myTextBox.Text += res.ToString() + "\n";
}
我在考虑这样的事情:
foreach (var task in taskArray)
{
var result = await task;
myTextBox.Text += result.ToString() + "\n";
}
但是经过测试和阅读循环中的await后,我知道它正在运行同步。有没有办法在主线程中连续处理结果?
答案 0 :(得分:2)
有几种解决方案,但最简单的方法是使用await Task.WhenAny()
,它返回一个已完成的Task
,然后您可以从任务列表中处理和删除,然后重复相同的操作直到列表是空的。
按要求提供的示例:
List<Task<int>> indexingArray = new List<Task<int>>(taskArray);
var results = new int[taskArray.Count];
while (taskArray.Any())
{
Task<int> completedTask = await Task.WhenAny(taskArray).ConfigureAwait(false);
results[indexingArray.IndexOf(completedTask)] = completedTask.Result;
taskArray.Remove(completedTask);
}
myTextBox.Text = string.Join("\n", results);
(我添加了一个索引集合来获取结果的正确索引。可能有更好的方法可以做到这一点,但问题是关于任务我将保持原样。)
答案 1 :(得分:1)
我想要实现的是在每个单独的任务完成后处理主线程中的结果,而不是等待所有结果
最简单的解决方案是引入一个var request = require('request');
console.time('10000 requests');
var j = 0;
for (var i = 0; i < 10000; i++) {
request('http://127.0.0.1:8001', function(error, response, body) {
console.log(body);
if (j > 9998) console.timeEnd('10000 requests');
j++;
});
}
方法,该方法对应于&#34; process&#34;概念。您已经拥有async
方式&#34;检索&#34;,您只需要引入async
操作&#34;检索并处理&#34;:
async
原样使用:
// (getWebPageCharCount is unchanged)
private Task GetAndDisplayWebPageCharCount(string url)
{
var res = await myCrawler.getWebPageCharCount(url);
myTextBox.Text += res.ToString() + "\n";
}
在旁注中,绝对不需要List<Task> taskArray = new List<Task>();
for (int i = 0; i < 100; i++)
taskArray.Add(GetAndDisplayWebPageCharCount("https://www.something.com"));
await Task.WhenAll(taskArray);
包裹Task.Run
。此外,&#34; 100个线程运行&#34;评论不正确;正在进行100个任务。