c# - for 循环内的异步 HTTP 请求,没有同时等待异步操作
问题描述
我正在构建一个解决方案,以从 for 循环内的 API 调用中找到所需的值。
我基本上需要将 for 循环的索引传递给 API,其中一个索引将返回所需的输出,在那一刻我希望 for 循环中断,但我需要有效地处理这个过程。我认为在没有 . 的情况下使其异步await
,因此当某些 API 返回所需的输出时,它会中断循环。
每个 API 调用大约需要 10 秒,所以如果我使这个异步或多线程,我会大大减少执行时间。
我还没有找到任何关于如何制作异步/不等待 HTTP 请求的好的方向。
有什么建议么?
for (int i = 0; i < 60000; i += 256)
{
Console.WriteLine("Incrementing_value: " + i);
string response = await client.GetStringAsync(
"http://localhost:7075/api/Function1?index=" + i.ToString());
Console.WriteLine(response);
if (response != "null")//
{
//found the desired output
break;
}
}
解决方案
您可以并行运行请求,并在找到所需输出后取消它们:
public class Program {
public static async Task Main() {
var cts = new CancellationTokenSource();
var client = new HttpClient();
var tasks = new List<Task>();
// This is the number of requests that you want to run in parallel.
const int batchSize = 10;
int requestId = 0;
int batchRequestCount = 0;
while (requestId < 60000) {
if (batchRequestCount == batchSize) {
// Batch size reached, wait for current requests to finish.
await Task.WhenAll(tasks);
tasks.Clear();
batchRequestCount = 0;
}
tasks.Add(MakeRequestAsync(client, requestId, cts));
requestId += 256;
batchRequestCount++;
}
if (tasks.Count > 0) {
// Await any remaining tasks
await Task.WhenAll(tasks);
}
}
private static async Task MakeRequestAsync(HttpClient client, int index, CancellationTokenSource cts) {
if (cts.IsCancellationRequested) {
// The desired output was already found, no need for any more requests.
return;
}
string response;
try {
response = await client.GetStringAsync(
"http://localhost:7075/api/Function1?index=" + index.ToString(), cts.Token);
}
catch (TaskCanceledException) {
// Operation was cancelled.
return;
}
if (response != "null") {
// Cancel all current connections
cts.Cancel();
// Do something with the output ...
}
}
}
请注意,此解决方案使用简单的机制来限制并发请求的数量,更高级的解决方案将使用信号量(如某些评论中所述)。
推荐阅读
- javascript - 将 props 传递给 styled-components
- nginx - Kubernetes nginx 入口控制器作为负载均衡器获取随机端口
- sql-server - 使用 JOIN 按日期仅选择一行
- scala - 忽略ScalaTest匹配中的案例类字段
- java - 如何在/连接两个 tomcat 服务器之间进行通信
- angular - 在 Angular 的 Formly Datepicker 中禁用未来日期
- enums - 变量中没有数据的枚举的二进制码序列化是否与引用静态值一样优化?
- powershell - 是否可以在 powershell 中启动 groovy 命令?
- apache-spark - 如何将两列的数据框(每行代表一对朋友 id)转换为具有 id 的数据及其所有朋友在一行中?
- python-3.x - 打开简历,找到模糊的图像