TPL Dataflow本地存储或类似的东西

我想要完成的是我有一个MaxDegreeOfParallelism = 4的动作块。 我想为每个并行路径创建一个会话对象的本地实例,所以我想要总共4个会话对象。 如果这是线程,我会创建类似于:

  ThreadLocal sessionPerThread = new ThreadLocal(() => new Session()); 

我知道块不是线程所以我正在寻找类似但是块的东西。 有没有办法创造这个?

这个区块在服务中并且可以连续运行数月。 在此期间,大量线程用于块的每个并发槽,因此线程本地存储不合适。 我需要一些与逻辑块槽相关的东西。 此块也永远不会完成,它会运行服务的整个生命周期。

注意:以上建议的答案对我要求的内容无效。 我特别要求与本地线程不同的东西,上面的答案是使用本地线程。 这完全是一个不同的问题。

听起来您已经知道,Dataflow块绝对不能保证块,执行和线程之间的关联。 即使最大并行度设置为4,所有4个任务也可以在同一个线程上执行。 或者单个任务可以在许multithreading上执行。

鉴于您最终希望为n级并行性重用昂贵服务的n个实例,让我们将数据流完全从图片中删除一分钟,因为它不会帮助(或直接阻碍)您对此的任何一般解决方案问题。 它实际上非常简单。 您可以使用ConcurrentStack ,其中T是您实例化的服务类型。 您的代码显示在方法(或委托)的顶部,代表您的一个并行工作单元:

 private ConcurrentStack reusableServices; private void DoWork() { T service; if (!this.reusableServices.TryPop(out service)) { service = new T(); // expensive construction } // Use your shared service. //// Code here. // Put the service back when we're done with it so someone else can use it. this.reusableServices.Push(service); } 

现在通过这种方式,您可以快速地看到,您创建了与DoWork()并行执行一样多的昂贵服务实例。 您甚至不必硬编码您期望的并行度。 它与您实际安排并行性的方式正交(因此线程池,数据流,PLINQ等无关紧要)。

所以你可以使用DoWork()作为你的Dataflow块的委托,然后你就可以了。

当然,这里没有关于ConcurrentStack神奇之处,除了push和pop周围的锁都内置在类型中,所以你不必自己动手。