亚洲精品久久久久久第一页-人妻少妇精彩视品一区二区三区-91国产自拍免费视频-免费一级a在线播放视频正片-少妇天天日天天射天天爽-国产大屁股喷水视频在线观看-操美女骚穴抽插性爱视频-亚洲 欧美 中文字幕 丝袜-成人免费无码片在线观看

線程上下文切換 多線程下的調(diào)用上下文 : CallContext


線程上下文切換 多線程下的調(diào)用上下文 : CallContext

文章插圖
| 總結(jié)/Edison Zhou
最近在分析現(xiàn)在團(tuán)隊的項目代碼(基于.NET Framework 4.5),經(jīng)常發(fā)現(xiàn)一個CallContext的調(diào)用,記得多年前的時候用到了它,但是印象已經(jīng)不深刻了,于是現(xiàn)在來復(fù)習(xí)一下 。
1 CallContext是個啥?
如果說,一個對象保證全局唯一,大家肯定會想到一個經(jīng)典的設(shè)計模式:單例模式 。但是,如果要使用的對象必須是線程內(nèi)唯一的呢?
在.NET Framework中,Microsoft給我們設(shè)計了一個CallContext類 。
命名空間:System.Runtime.Remoting.Messaging類型完全限定名稱:System.Runtime.Remoting.Messaging.CallContextCallContext類似于方法調(diào)用的線程本地存儲區(qū)的專用集合對象,并提供對每個邏輯執(zhí)行線程都唯一的數(shù)據(jù)槽 。數(shù)據(jù)槽不在其他邏輯線程上的調(diào)用上下文之間共享 。當(dāng) CallContext 沿執(zhí)行代碼路徑往返傳播并且由該路徑中的各個對象檢查時,可將對象添加到其中 。
簡而言之,CallContext提供線程(多線程/單線程)代碼執(zhí)行路徑中數(shù)據(jù)傳遞的能力 。
方法
描述
線程安全
SetData
存儲給定的對象并將其與指定名稱關(guān)聯(lián) 。

GetData
從System.Runtime.Remoting.Messaging.CallContext中檢索具有指定名稱的對象

LogicalSetData
將給定的對象存儲在邏輯調(diào)用上下文,并將其與指定名稱關(guān)聯(lián) 。

LogicalGetData
從邏輯調(diào)用上下文中檢索具有指定名稱的對象 。

FreeNamedDataSlot
清空具有指定名稱的數(shù)據(jù)槽 。

HostContext
獲取或設(shè)置與當(dāng)前線程相關(guān)聯(lián)的主機(jī)上下文 。在Web環(huán)境下等于System.Web.HttpContext.Current
2 探究CallContext方法
上面介紹了CallContext提供的核心方法,下面我們就來通過實踐來理解一下 。
準(zhǔn)備工作
這里準(zhǔn)備一個User類作為數(shù)據(jù)傳遞對象:
public class User{public string Id { get; set; }public string Name { get; set; }}測試1:GetData、SetData 與 FreeNamedDataSlot
測試代碼很簡單,就是在主線程 和 子線程之中分別傳遞User對象實例,看看最后的效果 。
public void TestGetSetData(){// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var user = new User(){Id = DateTime.Now.ToString(),Name = "Edison"};CallContext.SetData("key", user);var value1 = CallContext.GetData("key");Console.WriteLine(user == value1);// 異步線程執(zhí)行Task.Run(() =>{Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value2 = CallContext.GetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());});// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");value1 = CallContext.GetData("key");Console.WriteLine(value1 == user);// 清理數(shù)據(jù)槽CallContext.FreeNamedDataSlot("key");var value3 = CallContext.GetData("key");Console.WriteLine(value3 == null ?"NULL" : (value3 == value1).ToString());}上面示例代碼的運行結(jié)果如下圖所示:
線程上下文切換 多線程下的調(diào)用上下文 : CallContext

文章插圖
根據(jù)上圖所示的結(jié)果,基本可以得出以下兩個結(jié)論:
1、GetData、SetData方法只能用于單線程環(huán)境,如果發(fā)生了線程切換,存儲的數(shù)據(jù)也會隨之丟失 。
2、GetData 和 SetData 可以用于同一線程中的不同地方,傳遞數(shù)據(jù) 。
可以知道,要在多線程環(huán)境下使用,我們需要用到另外兩個方法:LogicalSetData 與 LogicalGetData 。
測試2:LogicalGetData、LogicalSetData 與 FreeNamedDataSlot


以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請您及時就醫(yī)或請專業(yè)人士給予相關(guān)指導(dǎo)!

「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對您有所幫助: