当线程死掉时,C#ThreadStaticAttribute标记的字段会自动释放吗?

时间:2010-01-15 21:21:33

标签: c# multithreading static

我发现了'ThreadStaticAttribute',我对此有很多疑问: 所有我之前依赖于线程的静态信息,都是作为一个静态字典实现的,TKey是Thread,当我想访问它时,我使用了Thread.CurrentThread,这是有效的。但这需要mantainance,因为如果一个线程死了,我必须从字典中删除相应的条目。我还需要考虑线程安全性以及许多其他问题。

通过使用ThreadStaticAttribute,所有这些问题似乎都得到了解决,但我需要确定它。我的问题是:在线程死之前,我是否需要以某种方式删除'ThreadStaticAttribute'标记字段的实例保留?那个领域的信息在哪里举行?它是在Thread对象的实例中,或类似的东西,所以当它不再使用时,垃圾收集器会自动丢弃它?是否有性能损失?什么?它比使用Keyed集合更快吗?

拜托,我需要澄清'ThreadStaticAttribute'的工作原理。

感谢。

2 个答案:

答案 0 :(得分:11)

不,您不需要在标有ThreadStatic的字段中删除值帮助的实例。当根对象无法再访问线程和对象时,垃圾收集器将自动拾取它们。

这里唯一的例外是,如果值实现IDisposable并且您想要主动处理它。通常,由于许多原因,这是一个难以解决的问题。没有实现IDisposable并且在ThreadStatic字段中的值更简单。

关于这个字段实际存储的位置,它有点无关紧要。您需要关心的是它的行为与.Net中的任何其他对象一样。

只有两个行为差异
  1. 该字段将为每个访问线程引用不同的值。
  2. 该字段的初始化程序只运行一次(实际上,拥有任何内容都是个坏主意)。

答案 1 :(得分:6)

将静态成员变量标记为[ThreadStatic]告诉编译器将其分配到线程的内存区域(例如,分配线程堆栈的位置)而不是全局内存区域。因此,每个线程都有自己的副本(保证初始化为该类型的默认值,例如null,0,false等;不要使用内联初始化器,因为它们只会为一个线程初始化它)。

因此,当线程消失时,其内存区域也会消失,释放引用。当然,如果它需要更多的立即处理(打开文件流等)而不是等待后台垃圾收集,您可能希望确保在线程退出之前执行此操作。

可用的[ThreadStatic]空间量可能有限,但对于理智的用途应该足够了。它应该比访问一个键控集合(更容易线程安全)快一些,我认为它与访问一个普通的静态变量相当。

更正:我听说过访问ThreadStatic变量比访问普通的静态变量要慢一些。我不确定它是否实际上比访问密钥集合更快,但它确实避免了孤儿问题(这是你的问题)并且需要锁定线程安全,这会使密钥收集方法复杂化。