C#类库的线程本地存储

我有一个非常古老但非常大的库,我正在考虑转换为C#类库。 现有库使用存储在TLS中的许多全局变量。 C#没有真正的全局变量概念,但一种解决方法是使用一个名为GlobalVar的静态类,并将它们全部放在这个类中,以便可以通过GlobalVar.xxxxxx访问它们

但是,我的想法是,这会破坏所有正在转换的现有代码,因为GlobalVar类将是一个普通的全局类而不是每个线程存储。 有没有办法让每个线程的这些全局变量? 即C#中__declspec(thread)静态的等价物是什么?

我应该补充一点,我讨厌全局变量。 我认为它们往往是设计不佳的结果。 但是,由于严格的时间限制,第一阶段是将库转换为C#,最小化,然后第2阶段将重新设计它们。

有ThreadLocal类(在4.0中引入)和ThreadStaticAttribute 。

ThreadStaticAttribute只能用于static字段。 ThreadLocal类可以在“普通”字段上使用,但速度较慢。

请注意,如果你不控制你所在的线程(例如你是一个ASP.NET页面,你开始使用“随机”预先使用的线程,或者你是一个ThreadPool的线程),那么你的“thread-static”(通常不是属性)变量将使用前一个线程的旧值进行预初始化。 (参见例如两种技术的故事:[ThreadStatic]属性和System.Web.HttpContext.Current.Items )

我忘记了,有一些Thread.AllocateDataSlot具有与其他类似的“目标”。

您可以使用[ThreadStatic]属性实现相同的线程本地存储,或使用ThreadLocal类在.Net 4中实现。

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

还有CallContext类,但其他方法可能更受欢迎 。

假设您将使用.NET 4.0,您可以拥有一个static ThreadLocal ,其中您的ThreadLocalData类将所有变量作为属性:

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

然后,您将访问如下属性:

 int i = Global.ThreadLocal.GlobalInt; 

您可以添加任何非线程局部的全局变量作为Global类的常规属性。