Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#类库的线程本地存储_C#_Multithreading_Global Variables - Fatal编程技术网

C#类库的线程本地存储

C#类库的线程本地存储,c#,multithreading,global-variables,C#,Multithreading,Global Variables,我有一个非常古老但非常大的库,我正在考虑将其转换为C#class库。现有库使用TLS中存储的许多全局变量。C#没有全局变量的真正概念,但一种解决方法是使用一个名为GlobalVar的静态类,并将它们全部放在这个类中,这样就可以通过GlobalVar.xxxxxx访问它们 然而,我的想法是,这将破坏所有正在转换的现有代码,因为GlobalVar类将是一个普通的全局类,而不是每线程存储。有没有办法让这些全局变量成为每个线程?i、 e.C中的u declspec(thread)static的等价物是什

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

然而,我的想法是,这将破坏所有正在转换的现有代码,因为GlobalVar类将是一个普通的全局类,而不是每线程存储。有没有办法让这些全局变量成为每个线程?i、 e.C中的u declspec(thread)static的等价物是什么

我应该补充一点,我讨厌全局变量。我认为它们往往是设计拙劣的结果。但是,由于时间限制,第一阶段是将库转换为C#,尽量减少麻烦,然后第二阶段是正确地重新设计它们。

有类(在4.0中引入)和

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

呵呵,你似乎坚持要教我们意大利语:-@xanatos
ThreadStaticAttribute只能在静态字段上使用
并不总是正确的。人们可能想声明一个每线程每实例的变量。意大利语不是很好,只是开玩笑,非常感谢您的帮助。尽管我有点担心最后一段关于使用线程池的内容。起初我不认为这是一个问题,但这是未来可能需要考虑的问题。@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)