[英]identifiing the simultaneous tasks in a TPL dataflow
我在TPL數據流塊中有1000個元素,每個元素都會調用外部Web服務。
Web服務最多支持10個同時呼叫,這可以通過以下方式輕松實現:
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 10
...
}
Web服務要求每個調用都有一個唯一的id,它將其與其他同時調用區分開來。 理論上這應該是一個guid,但實際上第11個GUID將失敗 - 因為服務器上的限制機制很難識別第一個調用已完成。
供應商建議我們回收guids,保持10個正在使用。
我打算有一個GUID數組,每個任務都會使用(Interlocked.Increment(ref COUNTER)%10)作為數組索引
編輯:我剛剛意識到這不起作用! 它假設任務將按順序完成,我們可能無法將其作為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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.