gpt4 book ai didi

c# - 识别 TPL 数据流中的同时任务

转载 作者:太空宇宙 更新时间:2023-11-03 22:57:21 25 4
gpt4 key购买 nike

我在 TPL 数据流 block 中有 1000 个元素,每个元素都会调用外部网络服务。

Web 服务最多支持 10 个同时调用,这很容易实现:

new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 10
...
}

Web 服务要求每个调用都传递一个唯一的 ID,以区别于其他同时调用。理论上这应该是一个 GUID,但实际上第 11 个 GUID 将失败 - 因为服务器上的节流机制识别第一个调用已完成的速度很慢。

供应商建议我们回收 guid,保留 10 个在使用中。

我打算有一个 GUID 数组,每个任务将使用 (Interlocked.Increment(ref COUNTER) % 10 ) 作为数组索引

编辑:我才意识到这行不通!它假定任务将按顺序完成,但它们可能不会我可以将其实现为一个 ID 队列,其中每个任务借用并返回一个 ID,但问题仍然存在,是否有更简单、预构建线程安全的方法来执行此操作?

(永远不会有足够的调用让 COUNTER 溢出)

但是 C#(我是 .net 的新手)让我多次感到惊讶,因为我正在实现一些已经存在的东西。

是否有更好的线程安全方式让每个任务从 ID 池中回收?

最佳答案

创建资源池就是这样的情况System.Collections.ConcurrentBag<T>是有用的。将其包裹在 BlockingCollection<T> 中使代码更简单。

class Example
{
private readonly BlockingCollection<Guid> _guidPool;
private readonly TransformBlock<Foo, Bar> _transform;

public Example(int concurrentLimit)
{
_guidPool = new BlockingCollection<Guid>(new ConcurrentBag<Guid>(), concurrentLimit)
for(int i = 0: i < concurrentLimit; i++)
{
_guidPool.Add(Guid.NewGuid());
}

_transform = new TransformBlock<Foo, Bar>(() => SomeAction,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = concurrentLimit
//...
});
//...
}

private async Task<Bar> SomeAction(Foo foo)
{
var id= _guidPool.Take();
try
{
//...
}
finally
{
_guidPool.Add(id);
}
}
}

关于c# - 识别 TPL 数据流中的同时任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44752011/

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