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

Mig*_*elo 18 c# static multithreading

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

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

请,我需要澄清'ThreadStaticAttribute'的工作原理.

谢谢.

Jar*_*Par 12

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

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

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

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


Rob*_*ker 6

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

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

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

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

  • 编译器对于`ThreadStatic`属性完全没有任何作用.它完全由CLR处理 (3认同)