gpt4 book ai didi

c# - TPL 数据流本地存储或类似的东西

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

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

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

我知道 block 不是线程,所以我正在寻找类似但用于 block 的东西。有什么方法可以创建它吗?

此 block 在服务中并连续运行数月。在那段时间里, block 的每个并发槽都使用了大量线程,因此线程本地存储是不合适的。我需要一些绑定(bind)到逻辑 block 插槽的东西。此 block 也永远不会完成,它运行服务的整个生命周期。

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

最佳答案

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

鉴于您最终想要为您的 n 并行度重用昂贵服务的 n 个实例,让我们暂时不考虑数据流,因为它不会帮助(或直接阻碍)您对此问题的任何通用解决方案。其实很简单。您可以使用 ConcurrentStack<T> , 其中T是实例化成本高昂的服务类型。您的代码出现在方法(或委托(delegate))的顶部,代表您的并行工作单元之一:

private ConcurrentStack<T> 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() 作为数据流 block 的委托(delegate),就可以开始了。

当然,ConcurrentStack<T> 并没有什么神奇之处在这里,除了 push 和 pop 周围的锁是内置在类型中的,所以你不必自己做。

关于c# - TPL 数据流本地存储或类似的东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15265761/

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