当前位置: 移动技术网 > IT编程>开发语言>.net > AsnycLocal与ThreadLocal

AsnycLocal与ThreadLocal

2019年01月16日  | 移动技术网IT编程  | 我要评论
AsnycLocal与ThreadLocal AsnyncLocal与ThreadLocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在: AsyncLocal变量可以在父子线程中传递,创建子线程时父线程会将自己的AsyncLocal类型的上下文变量赋值到子线程中,但是, ...

asnyclocal与threadlocal

asnynclocal与threadlocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在:

  • asynclocal变量可以在父子线程中传递,创建子线程时父线程会将自己的asynclocal类型的上下文变量赋值到子线程中,但是,当子线程改变线程上下文中asnyclocal变量值后,父线程不会同步改变。也就是说asnyclocal变量只会影响他的子线程,不会影响他的父级线程。
  • treadlocal只是当前线程的上下文变量,不能在父子线程间同步。
using system;
using system.threading;
using system.threading.tasks;

namespace await_aysnc
{
    class program
    {
        static threadlocal<int> threadobj = new threadlocal<int>();
        static asynclocal<int> asyncobj = new asynclocal<int>();

        static void main(string[] args)
        {
            asyncobj.value = 1;
            threadobj.value = 1;
            console.writeline($"task执行前:asyncobj= {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid}");
            task.run(async() =>
            {
                console.writeline($"runasync异步执行前:asyncobj= {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid}");
                await runasync();
                console.writeline($"runasync异步执行后:asyncobj = {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid}");
            });
            console.writeline($"task执行后:asyncobj= {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid}");
            console.read();
        }

        static async task runasync()
        {           
            console.writeline($"delay异步执行前:asyncobj = {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid} ");
            asyncobj.value = 2;
            threadobj.value = 2;
            await task.delay(100);
            console.writeline($"delay异步执行后:asyncobj = {asyncobj.value} threadobj= {threadobj.value} threeadid = {thread.currentthread.managedthreadid}");
        }
    }

}
task执行前:asyncobj= 1 threadobj= 1 threeadid = 1
task执行后:asyncobj= 1 threadobj= 1 threeadid = 1
runasync异步执行前:asyncobj= 1 threadobj= 0 threeadid = 3
delay异步执行前:asyncobj = 1 threadobj= 0 threeadid = 3
delay异步执行后:asyncobj = 2 threadobj= 0 threeadid = 4
runasync异步执行后:asyncobj = 1 threadobj= 0 threeadid = 4

从结果上可以看出一下结论:

  • runasync执行前threadlocal值被切成0即threadlocal变量在新线程里面没有继承主线程的上下文变量,但是asynclocal继承了。
  • delay返回后,线程id变了,同时,theadlocal中的变量为0。
  • runasync结束后aynclocal又切回主线程的上下文值,,同样threadlocal中的值丢失。
  • 由于await执行完返回之后,.net会在线程池中随机选取一个线程来执行await之后的逻辑,所以,await之后同时也会有一定几率获取到之前的线程,如果出现这种情形,treadlocal会获取到之前的上下文,此时会出现意料之外的问题,从现象上看报错可能会是一个概率性问题。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网