CallContext.SetData () - доступен ли объект, когда поток становится активным-неактивным-активным (TPL)?

Ребята,

Допустим, я сохраняю три новых экземпляра объекта Car с помощью CallContext.SetData () из потока 10, 11, 12. Эти потоки завершают выполнение. Затем я выполняю другую многопоточную операцию (возможно, отличную от первой), в которой используются потоки 10, 11, 12. Будет ли GetData () извлекать те же три объекта, которые я сохранил? Или контекст как-то изменился, и эти объекты исчезли?

Мой конкретный вариант использования - это параллельная библиотека задач. Я использую TPL для распараллеливания некоторых операций и хочу понять, что происходит с данными, хранящимися через CallContext.SetData () между вызовами TPL.

EDIT
Согласно предложению @wageoghe, я попробовал ThreadLocal, и он сработал!

обновленный код, чтобы доказать это:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TlsTest
{

    public class Program
    {

        public static void Main()
        {
            Console.WriteLine( "-------using threadpool---------" );
            UseThreadPool();
            Console.WriteLine( "-------using tasks---------" );
            UseTasks();
            Console.WriteLine( "-------using parallel for---------" );
            UseParallelFor();
            Console.ReadKey();
        }

        public static void UseThreadPool()
        {

            var finish = new CountdownEvent( TotalThreads );

            for ( int i = 0 ; i < TotalThreads ; i++ )
            {
                ThreadPool.QueueUserWorkItem( x =>
                {
                    int id = Thread.CurrentThread.ManagedThreadId;

                    Thread.Sleep( SleepMilliseconds );

                    if ( ThreadId.IsValueCreated )
                    {
                        Console.WriteLine( "thread [{0}], tls.thread [{1}] - value already in Tls" , id , ThreadId.Value );                        
                    }
                    else
                    {                        
                        Console.WriteLine( "thread [{0}] - no Tls value" , id );
                        ThreadId.Value = id;
                    }
                    Thread.Sleep( SleepMilliseconds );
                    finish.Signal();
                } );
            }
            finish.Wait();
        }

        public static void UseTasks()
        {
            const TaskCreationOptions taskCreationOpt = TaskCreationOptions.None;

            var allTasks = new Task[ TotalThreads ];
            for ( int i = 0 ; i < TotalThreads ; i++ )
            {
                Task task = Task.Factory.StartNew( () =>
                {
                    int id = Thread.CurrentThread.ManagedThreadId;

                    Thread.Sleep( SleepMilliseconds );

                    if ( ThreadId.IsValueCreated )
                    {
                        Console.WriteLine( "thread [{0}], tls.thread [{1}] - value already in Tls" , id , ThreadId.Value );
                    }
                    else
                    {
                        Console.WriteLine( "thread [{0}] - no Tls value" , id );
                        ThreadId.Value = id;                        
                    }

                    Thread.Sleep( SleepMilliseconds );

                } , taskCreationOpt );
                allTasks[ i ] = task;
            }
            Task.WaitAll( allTasks );
        }

        public static void UseParallelFor()
        {

            var options = new ParallelOptions();
            options.MaxDegreeOfParallelism = 8;
            Parallel.For( 0 , TotalThreads , options , i =>
            {
                int id = Thread.CurrentThread.ManagedThreadId;

                Thread.Sleep( SleepMilliseconds );

                if ( ThreadId.IsValueCreated )
                {
                    Console.WriteLine( "thread [{0}], tls.thread [{1}] - value already in Tls" , id , ThreadId.Value );
                }
                else
                {
                    Console.WriteLine( "thread [{0}] - no Tls value" , id );
                    ThreadId.Value = id;                                        
                }

                Thread.Sleep( SleepMilliseconds );

            } );            
        }

        private static readonly ThreadLocal<int> ThreadId = new ThreadLocal<int>();
        private const int TotalThreads = 100;
        private const int SleepMilliseconds = 500;

    }    
}
7
задан SFun28 4 February 2011 в 23:51
поделиться