gpt4 book ai didi

c# - 如何在一个完成的线程满足条件后立即取消其他线程

转载 作者:太空狗 更新时间:2023-10-30 01:03:08 26 4
gpt4 key购买 nike

我有一个 ASP.NET MVC 应用程序,它需要检查 3 个远程 API 服务器上是否存在某些内容。应用程序将一个 ID 传递给每个 API,然后返回 true 或 false。代码如下所示。

public class PingController
{
public async Task<bool> IsFound(int id)
{
var servers = new ['a.com', b.com', 'c.com'];
var result = await foundAtServers(id, servers);
return result;
}

private async Task<bool> foundAtServers(int id, string[] servers)
{
var tasks = from server in servers
select checkServer(id, server);

return await.Task.WhenAll(tasks.ToArray());
}

private async Task<bool> checkServer(id, server)
{
var request = new HttpRequestMessage(HttpMethod.Get, server+"/api/exists"+id);
var client = new HttpClient();

var task = await client.SendAsync(request);
var response = await task.Content.ReadAsStringAsync();

return bool.Parse(response);
}
}

此代码目前异步检查所有 3 个 API,但会等到所有 HttpClient 调用完成后 MVC 操作才能返回。

一旦一个 API 返回 true,我想立即在 Action 上返回 true,而不是等待其他任务完成。

C# Task 类有 .WaitAll 和 .WaitAny,但它们也不起作用。由于我需要取消其他 HttpClient 请求,我想我需要使用 CancellationToken 但我不知道如何将它用于此结构。

干杯。

最佳答案

如果想立即返回,可以使用Task.WhenAny代替Task.WhenAll。这不会取消正在进行的任务,但可以让您尽快返回:

private async Task<bool> FoundAtServersAsync(int id, string[] servers)
{
var tasks = (from server in servers
select checkServer(id, server)).ToList();

while (tasks.Count > 0)
{
var finishedTask = await Task.WhenAny(tasks);
if (finishedTask.Result)
{
return finishedTask.Result;
}

tasks.Remove(finishedTask);
}
return false;
}

这将丢弃其他任务。这意味着如果在其中一个内部抛出任何异常,它将被吞噬。

编辑:

如果您关心实际取消其他任务,请考虑将您的 CancellationToken 传递给 overload of SendAsync which takes one ,并在收到值后调用 CancellationTokenSource.Cancel。请注意,这意味着您还需要处理它们将抛出的 OperationCanceledException

如果它们无关紧要,我会像上面那样简单地丢弃它们。

关于c# - 如何在一个完成的线程满足条件后立即取消其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30577806/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com