C# 如何在阵列中运行所有任务并连续处理结果(异步、等待)?

C# 如何在阵列中运行所有任务并连续处理结果(异步、等待)?,c#,multithreading,asynchronous,async-await,C#,Multithreading,Asynchronous,Async Await,我有以下代码: List<Task<int>> taskArray = new List<Task<int>>(); for (int i = 0; i < 100; i++) { taskArray.Add(myCrawler.getWebPageCharsCount("https://www.something.com")); }

我有以下代码:

        List<Task<int>> taskArray = new List<Task<int>>();

        for (int i = 0; i < 100; i++)
        {
            taskArray.Add(myCrawler.getWebPageCharsCount("https://www.something.com"));
        }
        var results = await Task.WhenAll(taskArray);

        foreach (var res in results)
        {
            myTextBox.Text += res.ToString() + "\n";
        }
我在想这样的事情:

    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;
        });
    }
        foreach (var task in taskArray)
        {
            var result = await task;
            myTextBox.Text += result.ToString() + "\n";
        }

但在测试和阅读了wait in循环之后,我知道它正在同步运行。有没有办法在主线程中连续处理结果

有几种解决方案,但最简单的是使用
wait Task.whenay()
,它返回一个已完成的
任务,然后处理该任务并将其从任务列表中删除,然后重复相同的操作,直到列表为空

请求的示例

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);
List indexingArray=新列表(taskArray);
var results=newint[taskArray.Count];
while(taskArray.Any())
{
Task completedTask=等待Task.WhenAny(taskArray).ConfigureAwait(false);
结果[indexingArray.IndexOf(completedTask)]=completedTask.Result;
taskArray.Remove(completedTask);
}
myTextBox.Text=string.Join(“\n”,结果);

(我添加了一个索引集合,以获得结果的正确索引。可能有更好的方法,但问题是关于任务,所以我将保持原样)。

有几种解决方案,但最简单的是使用
等待任务。WhenAny()
,它返回已完成的
任务,然后处理并从任务列表中删除,然后重复相同操作,直到列表为空

请求的示例

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);
List indexingArray=新列表(taskArray);
var results=newint[taskArray.Count];
while(taskArray.Any())
{
Task completedTask=等待Task.WhenAny(taskArray).ConfigureAwait(false);
结果[indexingArray.IndexOf(completedTask)]=completedTask.Result;
taskArray.Remove(completedTask);
}
myTextBox.Text=string.Join(“\n”,结果);
(我添加了一个索引集合,以获得结果的正确索引。可能有更好的方法可以做到这一点,但由于问题是关于任务,我将保持原样)

我想要实现的是在每个任务完成后在主线程中处理结果,而不是等待所有结果

最简单的解决方案是引入一个与“流程”概念相对应的
async
方法。您已经有了一个
async
的“检索”方式,您只需要引入一个
async
的“检索和处理”操作:

这样使用:

List<Task> taskArray = new List<Task>();
for (int i = 0; i < 100; i++)
  taskArray.Add(GetAndDisplayWebPageCharCount("https://www.something.com"));
await Task.WhenAll(taskArray);
List taskArray=new List();
对于(int i=0;i<100;i++)
taskArray.Add(GetAndDisplayWebPageCharCount(“https://www.something.com"));
wait Task.WhenAll(任务数组);
另一方面,完全不需要
Task.Run
wrapping
HttpClient.GetStringAsync
。此外,“100线程运行”备注不正确;有100项任务正在进行中

我想要实现的是在每个任务完成后在主线程中处理结果,而不是等待所有结果

最简单的解决方案是引入一个与“流程”概念相对应的
async
方法。您已经有了一个
async
的“检索”方式,您只需要引入一个
async
的“检索和处理”操作:

这样使用:

List<Task> taskArray = new List<Task>();
for (int i = 0; i < 100; i++)
  taskArray.Add(GetAndDisplayWebPageCharCount("https://www.something.com"));
await Task.WhenAll(taskArray);
List taskArray=new List();
对于(int i=0;i<100;i++)
taskArray.Add(GetAndDisplayWebPageCharCount(“https://www.something.com"));
wait Task.WhenAll(任务数组);

另一方面,完全不需要
Task.Run
wrapping
HttpClient.GetStringAsync
。此外,“100线程运行”备注不正确;有100项任务正在进行。

请查看。这可能对你有帮助。看。请看一下。这可能对你有帮助。你能给我举个例子吗?我提出了“递归”解决方案(不完全是递归的,因为每次调用都应该在等待之后,当另一个调用继续时,完成-但是异步操作何时已经完成,我的意思是在新调用期间,它将立即被处理)但与WhenAll()的解决方案相比,它似乎对资源更贪婪一些。这是一个O(N^2)算法。你能给我举个例子吗?我提出了“递归”解决方案(不完全是递归的,因为每次调用都应该在等待之后,当另一个调用继续时,完成-但是异步操作何时已经完成,我的意思是在新调用期间,它将立即被处理)但与WhenAll()的解决方案相比,它似乎对资源更贪婪一些。这是一个O(N^2)算法。也许还有一个小问题:它不会按原始顺序输出结果,从他最初的代码来看,这似乎是一个要求?@sellotape:我相信这不是OP想要的:
想要实现的是在每个任务完成后在主线程中处理结果。
。也许还有一个小问题:这不会按原始顺序输出结果,从他的原始代码来看,这似乎是一个要求?@sellotape:我相信这不是OP想要的:
想要实现的是在每个任务完成后在主线程中处理结果