gpt4 book ai didi

c# - 节流asp .net中的异步任务,限制N个成功任务

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

我使用的是 Asp .Net 4.5.1。我有任务要运行,调用网络服务,有些可能会失败。我需要运行 N 个成功的任务,这些任务执行一些轻度 CPU 工作,主要调用网络服务,然后停止,我想节流。

例如,假设某个集合中有 300 个 URL。我们需要运行一个名为 Task<bool> CheckUrlAsync(url) 的函数对它们中的每一个进行限制,意味着,例如,“同时”只有 5 个运行(换句话说,在任何给定时间最多使用 5 个连接)。另外,我们只想执行 N(假设 100)次成功的操作,然后停止。

我读过 thisthis但我仍然不确定什么是正确的方法。

你会怎么做?

  1. 假设 ASP .Net
  2. 假设 IO 调用(对网络服务的 http 调用),没有繁重的 CPU 操作。

最佳答案

使用 Semaphore slim。

var semaphore = new SemaphoreSlim(5);
var tasks = urlCollection.Select(async url =>
{
await semaphore.WaitAsync();
try
{
return await CheckUrlAsync(url);
}
finally
{
semaphore.Release();
}
};
while(tasks.Where(t => t.Completed).Count() < 100)
{
await.Task.WhenAny(tasks);
}

虽然我更愿意使用 Rx.Net 来生成一些更好的代码。

using(var semaphore = new SemaphoreSlim(5))
{
var results = urlCollection.ToObservable()
.Select(async url =>
{
await semaphore.WaitAsync();
try
{
return await CheckUrlAsync(url);
}
finally
{
semaphore.Release();
}
}).Take(100).ToList();
}

好吧……这会很有趣。

public static class SemaphoreHelper
{
public static Task<T> ContinueWith<T>(
this SemaphoreSlim semaphore,
Func<Task<T>> action)
var ret = semaphore.WaitAsync()
.ContinueWith(action);
ret.ContinueWith(_ => semaphore.Release(), TaskContinuationOptions.None);
return ret;
}
var semaphore = new SemaphoreSlim(5);
var results = urlCollection.Select(
url => semaphore.ContinueWith(() => CheckUrlAsync(url)).ToList();

我确实需要补充一点,目前的代码仍然会运行所有 300 个 URL,只是会更快地返回……仅此而已。您需要将取消 token 添加到 semaphore.WaitAsync(token) 以取消排队的工作。我再次建议为此使用 Rx.Net。使用 Rx.Net 获取取消 token 以使用 .Take(100) 会更容易。

关于c# - 节流asp .net中的异步任务,限制N个成功任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24849247/

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