TPL数据流本地存储或类似的东西 [英] TPL Dataflow local storage or something like it

查看:253
本文介绍了TPL数据流本地存储或类似的东西的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做到的是我有一个 MaxDegreeOfParallelism = 4 A操作块。我想创建一个会话对象,我为每个并行路径的一个本地实例,所以我想以总价4会话对象。如果这是线程我会创造这样的:

What I'm trying to accomplish is I have a action block with MaxDegreeOfParallelism = 4. I want to create one local instance of a session object I have for each parallel path, So I want to total of 4 session objects. If this was threads I would creating something like:

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



我知道块不是线程,以便我在寻找类似的东西,但对于块。任何方法来创建这个?

I know blocks are not threads so I'm looking for something similar but for blocks. Any way to create this?

这块是一个服务,运行好几个月。在这段时间内吨线程被用于该块的每个同步时隙所以线程本地存储是不恰当的。我需要的东西绑在逻辑块插槽。同时此块无法完成,它运行的服务的整个生命周期。

This block is in a service and runs for months on end. During that time period tons of threads are used for each concurrent slot of the block so thread local storage is not appropriate. I need something tied to the logical block slot. Also this block never completes, it runs the entire lifetime of the service.

请注意:以上建议的答案是无效的什么,我问。我专门问的东西比线程不同的地方和上面的回答是使用线程本地。这完全是一个不同的问题。

Note: The above suggested answer is not valid for what I am asking. I'm specifically asking for something different than thread local and the above answer is using thread local. This is a different question entirely.

推荐答案

,因为它听起来像你已经知道,数据流模块提供绝对没有块之间的相关性保障,执行和线程。即使最大并行设置为4,所有4个任务可以在相同的线程上执行。或单个任务可以执行许多线程。

As it sounds like you already know, Dataflow blocks provide absolutely no guarantee of correlation between blocks, execution, and threads. Even with max parallelism set to 4, all 4 tasks could be executing on the same thread. Or an individual task may execute on many threads.

既然你最终要重用的 N 的昂贵的服务的实例您的 ñ的并行度,让我们完全不搭的数据流出来的画面一分钟,因为它没有任何通用的解决方案,以帮助解决这个问题(或者直接阻碍)你。这其实很简单。您可以使用 ConcurrentStack< T> ,其中 T 为您服务的类型是实例昂贵。你必须出现在方法(或委托)的顶部,代表工作的平行单位之一代码:

Given that you ultimately want to reuse n instances of an expensive service for your n degrees of parallelism, let's take dataflow completely out of the picture for a minute, since it doesn't help (or directly hinder) you from any general solution to this problem. It's actually quite simple. You can use a ConcurrentStack<T>, where T is the type of your service that is expensive to instantiate. You have code that appears at the top of the method (or delegate) that represents one of your parallel units of work:

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等并不重要)。

Now in this way, you can quickly see that you create exactly as many instances of your expensive service as you have parallel executions of DoWork(). You don't even have to hard-code the degree of parallelism you expect. And it's orthogonal to how you actually schedule that parallelism (so threadpool, Dataflow, PLINQ, etc. doesn't matter).

所以你。可以直接使用的DoWork()作为数据流块的委托,你要走了。

So you can just use DoWork() as your Dataflow block's delegate and you're set to go.

当然,有什么魔力 ConcurrentStack< T> ; 在这里,除了围绕push和pop锁被内置到类型,所以你不必自己做

Of course, there's nothing magical about ConcurrentStack<T> here, except that the locks around push and pop are built into the type so you don't have to do it yourself.

这篇关于TPL数据流本地存储或类似的东西的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆