淺析C#中的AsnycLocal與ThreadLocal
AsnyncLocal與ThreadLocal都是存儲(chǔ)線程上下文的變量,但是,在實(shí)際使用過(guò)程中兩者又有區(qū)別主要的表現(xiàn)在:
- AsyncLocal變量可以在父子線程中傳遞,創(chuàng)建子線程時(shí)父線程會(huì)將自己的AsyncLocal類型的上下文變量賦值到子線程中,但是,當(dāng)子線程改變線程上下文中AsnycLocal變量值后,父線程不會(huì)同步改變。也就是說(shuō)AsnycLocal變量只會(huì)影響他的子線程,不會(huì)影響他的父級(jí)線程。
- TreadLocal只是當(dāng)前線程的上下文變量,不能在父子線程間同步。
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執(zhí)行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}"); Task.Run(async() => { Console.WriteLine($"RunAsync異步執(zhí)行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}"); await RunAsync(); Console.WriteLine($"RunAsync異步執(zhí)行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}"); }); Console.WriteLine($"Task執(zhí)行后:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}"); Console.Read(); } static async Task RunAsync() { Console.WriteLine($"Delay異步執(zhí)行前:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId} "); AsyncObj.Value = 2; ThreadObj.Value = 2; await Task.Delay(100); Console.WriteLine($"Delay異步執(zhí)行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}"); } } }
Task執(zhí)行前:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
Task執(zhí)行后:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
RunAsync異步執(zhí)行前:AsyncObj= 1 ThreadObj= 0 ThreeadId = 3
Delay異步執(zhí)行前:AsyncObj = 1 ThreadObj= 0 ThreeadId = 3
Delay異步執(zhí)行后:AsyncObj = 2 ThreadObj= 0 ThreeadId = 4
RunAsync異步執(zhí)行后:AsyncObj = 1 ThreadObj= 0 ThreeadId = 4
從結(jié)果上可以看出一下結(jié)論:
- RunAsync執(zhí)行前ThreadLocal值被切成0即ThreadLocal變量在新線程里面沒(méi)有繼承主線程的上下文變量,但是AsyncLocal繼承了。
- Delay返回后,線程id變了,同時(shí),TheadLocal中的變量為0。
- RunAsync結(jié)束后AyncLocal又切回主線程的上下文值,,同樣Threadlocal中的值丟失。
- 由于await執(zhí)行完返回之后,.net會(huì)在線程池中隨機(jī)選取一個(gè)線程來(lái)執(zhí)行await之后的邏輯,所以,await之后同時(shí)也會(huì)有一定幾率獲取到之前的線程,如果出現(xiàn)這種情形,TreadLocal會(huì)獲取到之前的上下文,此時(shí)會(huì)出現(xiàn)意料之外的問(wèn)題,從現(xiàn)象上看報(bào)錯(cuò)可能會(huì)是一個(gè)概率性問(wèn)題。
總結(jié)
到此這篇關(guān)于C#中AsnycLocal與ThreadLocal的文章就介紹到這了,更多相關(guān)C#的AsnycLocal與ThreadLocal內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單了解C#設(shè)計(jì)模式編程中的橋接模式
這篇文章主要介紹了C#設(shè)計(jì)模式編程中的橋接模式,橋接模式經(jīng)常應(yīng)用于解耦邏輯層與數(shù)據(jù)操作層,需要的朋友可以參考下2016-02-02簡(jiǎn)單實(shí)現(xiàn)winform編輯器
這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)winform編輯器,功能很簡(jiǎn)單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08C#如何優(yōu)雅的對(duì)WinForm窗體應(yīng)用程序進(jìn)行權(quán)限控制
經(jīng)常會(huì)出現(xiàn)winfrom頁(yè)面需要加載權(quán)限樹(shù),下面這篇文章主要給大家介紹了關(guān)于C#如何優(yōu)雅的對(duì)WinForm窗體應(yīng)用程序進(jìn)行權(quán)限控制的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法
這篇文章主要介紹了C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法,涉及C#針對(duì)數(shù)組的遍歷、校驗(yàn)及排序等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08

C#使用Socket發(fā)送和接收TCP數(shù)據(jù)實(shí)例