C#类库的线程本地存储
我有一个非常古老但非常大的库,我正在考虑将其转换为C#class库。现有库使用TLS中存储的许多全局变量。C#没有全局变量的真正概念,但一种解决方法是使用一个名为GlobalVar的静态类,并将它们全部放在这个类中,这样就可以通过GlobalVar.xxxxxx访问它们 然而,我的想法是,这将破坏所有正在转换的现有代码,因为GlobalVar类将是一个普通的全局类,而不是每线程存储。有没有办法让这些全局变量成为每个线程?i、 e.C中的u declspec(thread)static的等价物是什么 我应该补充一点,我讨厌全局变量。我认为它们往往是设计拙劣的结果。但是,由于时间限制,第一阶段是将库转换为C#,尽量减少麻烦,然后第二阶段是正确地重新设计它们。有类(在4.0中引入)和C#类库的线程本地存储,c#,multithreading,global-variables,C#,Multithreading,Global Variables,我有一个非常古老但非常大的库,我正在考虑将其转换为C#class库。现有库使用TLS中存储的许多全局变量。C#没有全局变量的真正概念,但一种解决方法是使用一个名为GlobalVar的静态类,并将它们全部放在这个类中,这样就可以通过GlobalVar.xxxxxx访问它们 然而,我的想法是,这将破坏所有正在转换的现有代码,因为GlobalVar类将是一个普通的全局类,而不是每线程存储。有没有办法让这些全局变量成为每个线程?i、 e.C中的u declspec(thread)static的等价物是什
ThreadStaticAttribute
只能用于static
字段。ThreadLocal
类可用于“正常”字段,但速度较慢
请注意,如果您不控制您所在的线程(例如,您是ASP.NET的一个页面,从一个“随机”的预使用线程开始,或者您是一个线程池的线程),那么您的“线程静态”(通常不是属性)变量将使用前一个线程的旧值进行预初始化。(参见示例)
我忘记了,有一个线程具有与其他线程类似的“目标”。您可以使用
[ThreadStatic]
属性或在.Net 4中使用ThreadLocal
类实现相同的线程本地存储
[ThreadStatic]
private static string MyThreadGlobal;
private ThreadLocal<string> MyThreadGlobal = new ThreadLocal<string>();
[ThreadStatic]
私有静态字符串;
private ThreadLocal MyThreadGlobal=new ThreadLocal();
还有一个类,但其他方法可能是首选的。假设您要使用.NET 4.0,您可以使用一个
静态ThreadLocal
,其中ThreadLocalData
类将所有变量作为属性:
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; }
}
}
您可以添加任何非线程本地的全局变量作为
全局类的常规属性。允许线程以独占方式访问其自身版本的线程的主要方法有三种
[ThreadStatic]
private static string MyThreadGlobal;
private ThreadLocal<string> MyThreadGlobal = new ThreadLocal<string>();
反对
1-[ThreadStatic]
实现非常简单,可以通过使用[ThreadStatic]
属性对静态字段进行签名来完成
[ThreadStatic] static int y;
现在,每个线程都会看到一个单独的y副本;
不幸的是,[ThreadStatic]
不适用于实例字段
2-线程本地
它是framework4.0
的新功能,为静态字段和实例字段提供线程本地存储。
此外,您可以为每个线程提供默认值,并且该值将被惰性地计算
static ThreadLocal<int> y = new ThreadLocal<int> (() => 10); //Static variable
ThreadLocal<int> y = new ThreadLocal<int> (() => 10); //Instance variable
呵呵,你似乎坚持要教我们意大利语:-@xanatosThreadStaticAttribute只能在静态字段上使用
并不总是正确的。人们可能想声明一个每线程每实例的变量。意大利语不是很好,只是开玩笑,非常感谢您的帮助。尽管我有点担心最后一段关于使用线程池的内容。起初我不认为这是一个问题,但这是未来可能需要考虑的问题。@UweKeim我感到很羞愧:-(有趣的是,我总是用英语阅读MSDN页面:-)但MSDN喜欢给我看意大利语版本(此时我已将其设置为向我显示页面的原始版本,但它仍在it页面上用英文文本重定向我)@UweKeim您是否看到我指向it资源的其他链接?
// The same LocalDataStoreSlot object can be used across all threads.
LocalDataStoreSlot y= Thread.GetNamedDataSlot ("slotName");
object data = Thread.GetData (y);
Thread.SetData (y, value)