Are you familiar with [ThreadStatic]?
2011-02-27 20:49 DanielWise 阅读(809) 评论(0) 收藏 举报如果你正在寻找一些关于线程本地存储的内容,你可能会对performance comparison between Thread.SetData and [ThreadStatic].感兴趣。
ThreadStatic 超级酷,如果你有一个静态变量,你可以通过在属性上面设置它来使这个属性对“每个线程”是静态的。这是一个简单的绕过使用静态变量时的线程安全性问题的方法- 由于它们是一个线程一个的,当你更新它们时你不必使用锁。
[ThreadStatic] private static string Foo;
现在可以绊倒你的就是初始化了。
[ThreadStatic] private static string Foo = "the foo string";
TreadStatic 在静态构造函数中初始化 - 它只执行一次。所以只有当静态构造函数执行时,第一个执行的线程才会被赋值"the foo string".当顺序访问所有的线程时,Foo 仍然是未初始化的空值。
最好的绕过这个问题的方法是使用一个属性来访问Foo属性。
[ThreadStatic]
private static string _foo;
public static string Foo
{
get
{
if (_foo == null)
{
_foo = "the foo string";
}
return _foo;
}
}
如果你有一些可以合理地设置为空值的属性,你可以总是使用一个静态线程布尔属性"_fooInitialized".
[ThreadStatic]
private static string _foo;
[ThreadStatic]
private static bool _fooInitialized;
public static string Foo
{
get
{
if (!_fooInitialized)
{
_fooInitialized = true;
_foo = "the foo string";
}
return _foo;
}
}
而且如果你有很多布尔型变量,你可能想要节省空间;无论你是否相信一个布尔型变量占据珍贵的比特(可以通过打印出Marshal.SizeOf(typeof(bool))来获取额外的证据)。
你可以把它们合并成一个比特变量来节省空间。
[ThreadStatic]
private static string _foo;
[ThreadStatic]
private static string _goo;
[ThreadStatic]
private static BitVector32 _state = new BitVector32();
private const int stateFooInitialized = 0x0001;
private const int stateGooInitialized = 0x0002;
// ... 0x0004, 0x0008 ...
public static string Foo
{
get
{
if (!_state[stateFooInitialized])
{
_state[stateFooInitialized] = true;
_foo = "the foo string";
}
return _foo;
}
}
public static string Goo
{
get
{
if (!_state[stateGooInitialized])
{
_state[stateGooInitialized] = true;
_goo = "the goo string";
}
return _goo;
}
}
作者:DanielWise
出处:http://www.cnblogs.com/danielWise/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号