检查异步任务状态并获取其结果
Posted
技术标签:
【中文标题】检查异步任务状态并获取其结果【英文标题】: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()
混淆了。
请查看以下问题:Async HTTP requests inside for loop without await 和 Task.WhenAny with cancellation of the non completed tasks and timeout。第一个可能正是您想要的。
截图:[PostAsync debug] 另一个问题的回答:***.com/a/69781897/11750551
【参考方案1】:
WhenAny 将返回第一个完成的任务。不是整数。为了得到结果,你可以等待同样的结果。
var completedTask = Task.WhenAny(tasks);
var result =await completedTask;
永远不要使用 task.result,因为它会阻止执行。
WhenAny 提供了一个异步迭代任务列表的选项。您可以直接在迭代循环中添加/删除要列出的任务。 (对于取消需要为所有任务传递相同的取消令牌)
【讨论】:
关于whenany的更多信息-请查看docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…以上是关于检查异步任务状态并获取其结果的主要内容,如果未能解决你的问题,请参考以下文章