【问题标题】:Check status of async tasks status and get their results检查异步任务状态并获取其结果
【发布时间】:2021-09-09 15:32:37
【问题描述】:

我是 C# 新手。 我想在不等待响应的情况下启动 4 PostAsync,然后检查它们中的任何一个是否已完成并且 HTTP 响应包含特定单词,然后取消其他异步任务。

如果已完成的PostAsync 不包含单词或失败,则运行另一个任务,使所有异步任务的总数保持在 4

private async void Button_Click(object sender, RoutedEventArgs e)
{
    List<Task> tasks = new List<Task>();
    for (int ctr = 0; ctr <= 2; ctr++)
    {
        tasks.Add(Web("https://google.com/api/", da));
    }
    
    var index = Task.WhenAny(tasks).Result;
}

public static async Task<string> Web(string url, string da)
{
     var response = await client.PostAsync(url,
         new StringContent(da, Encoding.UTF8, "application/json"));

     return response.Content.ReadAsStringAsync().Result; ;
}

我测试了上面的代码,但不知道如何获取已完成任务的结果,也不知道如何在失败的情况下添加另一个任务。

【问题讨论】:

  • WhenAny() 方法返回完成的任务对象。而不是使用Result,这是错误的,因为它阻塞,否定使用WhenAny()的全部好处,写var task = await Task.WhenAny(tasks)和task变量将包含完成的Task对象。至于取消其余的任务,只需确保任务是可取消的(即您已将取消令牌传递给每个任务),并触发取消令牌,即通过取消您在第一个获得令牌的取消令牌源地方。查看副本。
  • 我会注意到变量名index 具有误导性,因为Task.WhenAny() 返回的值不是索引,而是任务。您似乎将WhenAny() 与WaitAny() 混淆了。
  • 截图:[PostAsync debug] 另一个问题的回答:stackoverflow.com/a/69781897/11750551

标签: c# .net asynchronous async-await task


【解决方案1】:

WhenAny 将返回第一个完成的任务。不是整数。为了得到结果,你可以等待同样的结果。

   var completedTask = Task.WhenAny(tasks);

   var result =await completedTask;

永远不要使用 task.result,因为它会阻止执行。

WhenAny 提供了一个异步迭代任务列表的选项。您可以直接在迭代循环中添加/删除要列出的任务。 (对于取消需要为所有任务传递相同的取消令牌)

【讨论】:

猜你喜欢
  • 2020-01-27
  • 2013-12-27
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
相关资源
最近更新 更多