Thread Local Storage For C# Class Library

后端 未结 4 1696
不思量自难忘°
不思量自难忘° 2021-01-04 08:06

I have a very old but very large library which I am considering converting to a C# class library. The existing library uses a lot of global variables stored in the TLS. C# h

相关标签:
4条回答
  • 2021-01-04 08:11

    Presuming you're going to use .NET 4.0, you could have a static ThreadLocal<ThreadLocalData> where your ThreadLocalData class has all your variables as properties:

    class ThreadLocalData
    {
        public int GlobalInt { get; set; }
        public string GlobalString { get; set; }
    }
    
    class Global
    {
        static ThreadLocal<ThreadLocalData> _ThreadLocal =
            new ThreadLocal<ThreadLocalData>( () => new ThreadLocalData() );
    
        public static ThreadLocalData ThreadLocal
        {
           get { return _ThreadLocal.Value; }
        }
    }
    

    You would then access the properties like this:

    int i = Global.ThreadLocal.GlobalInt;
    

    You could add any global variables that are not thread-local as normal properties of the Global class.

    0 讨论(0)
  • 2021-01-04 08:12

    There are three main methods for allowing the thread to exclusively access its own version of thread-unsafe object.

    1- [ThreadStatic] The implementation is super easy and, it can be done through signing a static field with [ThreadStatic] attribute

    [ThreadStatic] static int y;
    

    Now each thread then sees a separate copy of y; unfortunately, [ThreadStatic] doesn't work with instance fields.

    2- ThreadLocal It is new to framework 4.0 and it provides thread-local storage for both static and instance fields. also, you can provide default value per each thread and that value is evaluated lazily.

    static ThreadLocal<int> y = new ThreadLocal<int> (() => 10);  //Static variable
    ThreadLocal<int> y = new ThreadLocal<int> (() => 10);  //Instance variable
    

    3- GetData and SetData In this approach, two methods of Thread class are using: GetData and SetData. These methods store data in thread-specific "Slots". A name should be specified for the slot, so the same slot can be used across all threads and they will get separate values.

     // The same LocalDataStoreSlot object can be used across all threads.
       LocalDataStoreSlot y= Thread.GetNamedDataSlot ("slotName");
       object data = Thread.GetData (y);
       Thread.SetData (y, value)
    
    0 讨论(0)
  • 2021-01-04 08:18

    There are the ThreadLocal class (introduced in 4.0) and the ThreadStaticAttribute.

    The ThreadStaticAttribute can be used only on static fields. The ThreadLocal class can be used on "normal" fields but it is slower.

    Be aware that if you don't control the thread you are on (for example you are a page of ASP.NET and you start on a "random" pre-used thread, or you are a thread of a ThreadPool), then your "thread-static" (in general, not the attribute) variables will be pre-initialized with the old values of the previous thread. (see for example A tale of two techniques: The [ThreadStatic] Attribute and System.Web.HttpContext.Current.Items)

    I was forgetting, there is the Thread.AllocateDataSlot that has similar "objectives" than the others.

    0 讨论(0)
  • 2021-01-04 08:30

    You can achieve the same thread local storage using the [ThreadStatic] attribute or in .Net 4 by using the ThreadLocal class.

    [ThreadStatic]    
    private static string MyThreadGlobal;
    
    private ThreadLocal<string> MyThreadGlobal = new ThreadLocal<string>();
    

    There's also the CallContext class but the other approaches are probably preferred.

    0 讨论(0)
提交回复
热议问题