Are you familiar with [ThreadStatic]?

本文探讨了.NET中Thread.SetData与[ThreadStatic]属性的性能对比,并详细介绍了使用[ThreadStatic]属性进行线程局部存储时可能出现的初始化问题及解决方法。

转载:http://blogs.msdn.com/jfoscoding/archive/2006/07/18/670497.aspx

 

If you're stuffing anything in thread local storage, you might be interested in the performance comparison between Thread.SetData and [ThreadStatic].

ThreadStatic is super-cool, if you have a static variable, you can make it static "per-thread" by placing the attribute on top.  This is one easy way to get around the thread-safety issues of working with statics - as they are per-thread, you do not have to take a lock when updating them.

[ThreadStatic]
private static string Foo;

Now the thing that can trip you up is initialization. 

[ThreadStatic]
private static string Foo = "the foo string";

The ThreadStatic is initialized in the static constructor - which only executes once.  So only the very first thread is assigned "the foo string" when the static constructor executes. When accessed in all subsequent threads, Foo is left at the uninitalized null value.

The best way to work around this is to use a property to access the Foo prop.

[ThreadStatic]
private static string _foo;

public static string Foo {
   get {
     if (_foo == null) {
         _foo = "the foo string";
     }
     return _foo;
   }
}

If you have something that can be legitimately set to null, you can always use a thread-static boolean "_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;
   }
}

And if you have a lot of booleans, you may want to save space; believe it or not a boolean hogs precious bits (for extra credit try printing out Marshal.SizeOf(typeof(bool)). 

You save on space by lumping them all into one bitvector... 

        [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;
            }
        }

转载于:https://www.cnblogs.com/flyingchen/archive/2008/01/22/1048664.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值