AsnycLocal与ThreadLocal
程序员文章站
2022-07-28 11:35:18
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会获取到之前的上下文,此时会出现意料之外的问题,从现象上看报错可能会是一个概率性问题。
上一篇: 这,帝王般的享受啊!
下一篇: 三分钟了解OKEx的ETH期权产品
推荐阅读
-
盛大游戏外包管理平台FCK列全盘目路分析与解决方案
-
【Skywalking】— Skywalking安装与使用
-
从URL静态化与动态化之争谈搜索引擎优化技术(SEO)的学习
-
php多线程pthreads的安装与使用,php多线程pthreads
-
解析mysql与Oracle update的区别
-
canvas游戏开发学习之五:运用样式与颜色(一)
-
【原】《DIV+CSS商业案例与网页布局开发精讲》读书笔记(2)_html/css_WEB-ITnose
-
YII Framework学习之request与response用法(基于CHttpRequest响应),yiichttprequest_PHP教程
-
php数组函数序列之array_flip() 将数组键名与值对调_PHP
-
使用php与ftp数据库连接代码