簡體   English   中英

如何在數組中運行所有任務並連續處理結果(異步,等待)?

[英]How to run all tasks in array and process the results continuously (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"));
        }

該方法如下所示:

    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個線程在運行,我要達到的目標是在完成每個任務后在主線程中處理結果,而不是等待所有結果,這將由以下代碼完成:

        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之后,我知道它正在同步運行。 有沒有辦法在主線程中連續處理結果?

有幾種解決方案,但是最簡單的方法是使用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);

(我添加了一個索引集合來為結果獲取正確的索引。可能有更好的方法來執行此操作,但是由於問題是關於任務的問題,我將其保持原樣)。

我要實現的是在完成每個任務后在主線程中處理結果,而不是等待所有結果

最簡單的解決方案是引入一種與該“過程”概念相對應的async方法。 您已經有了“檢索”的async方式,您只需要引入“檢索和處理”的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包裝HttpClient.GetStringAsync 另外,“正在運行100個線程”的注釋是不正確的。 正在進行100個任務

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM