【问题标题】:identifiing the simultaneous tasks in a TPL dataflow识别 TPL 数据流中的并发任务
【发布时间】:2017-11-28 20:07:44
【问题描述】:

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

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

new ExecutionDataflowBlockOptions
{
    MaxDegreeOfParallelism = 10
    ...
}

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

供应商建议我们回收 guid,保留 10 个处于活动状态。

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

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

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

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

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

【问题讨论】:

    标签: c# task-parallel-library tpl-dataflow


    【解决方案1】:

    创建资源池正是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);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多