如何在数据流块中为每个线程创建对象而不是为每个请求创建对象?

How to create object per thread in DataFlow Block but not object per request?

我有一个代码示例

var options = new ExecutionDataflowBlockOptions();
var actionBlock = new ActionBlock<int>(async request=>{
         var rand = new Ranodm();
         //do some stuff with request by using rand
},options);

此代码的问题在于,在每个请求中我都必须创建新的 rand 对象。有一种方法可以为每个线程定义一个 rand 对象并在处理请求时重复使用同一个对象吗?

感谢 Reed Copsey for the nice article 和 Theodor Zoulias 提醒 ThreadLocal<T>

The new ThreadLocal class provides us with a strongly typed, locally scoped object we can use to setup data that is kept separate for each thread. This allows us to use data stored per thread, without having to introduce static variables into our types. Internally, the ThreadLocal instance will automatically setup the static data, manage its lifetime, do all of the casting to and from our specific type. This makes developing much simpler.

A msdn example:

 // Demonstrates:
    //      ThreadLocal(T) constructor
    //      ThreadLocal(T).Value
    //      One usage of ThreadLocal(T)
    static void Main()
    {
        // Thread-Local variable that yields a name for a thread
        ThreadLocal<string> ThreadName = new ThreadLocal<string>(() =>
        {
            return "Thread" + Thread.CurrentThread.ManagedThreadId;
        });

        // Action that prints out ThreadName for the current thread
        Action action = () =>
        {
            // If ThreadName.IsValueCreated is true, it means that we are not the
            // first action to run on this thread.
            bool repeat = ThreadName.IsValueCreated;

            Console.WriteLine("ThreadName = {0} {1}", ThreadName.Value, repeat ? "(repeat)" : "");
        };

        // Launch eight of them.  On 4 cores or less, you should see some repeat ThreadNames
        Parallel.Invoke(action, action, action, action, action, action, action, action);

        // Dispose when you are done
        ThreadName.Dispose();
    }

所以你的代码应该是这样的:

ThreadLocal<Random> ThreadName = new ThreadLocal<Random>(() =>
{
    return new Random();
});


var options = new ExecutionDataflowBlockOptions
{
    MaxDegreeOfParallelism = 4,
    EnsureOrdered = false,
    BoundedCapacity = 4 * 8
};
var actionBlock = new ActionBlock<int>(async request =>
{
    bool repeat = ThreadName.IsValueCreated;
    var random = ThreadName.Value; // your local random class
    Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId},  
        repeat: ", repeat ? "(repeat)" : "");

 }, options);