public void TestLogicalGetSetData(){// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var user = new User(){Id = DateTime.Now.ToString(),Name = "Edison"};CallContext.LogicalSetData("key", user);var value1 = CallContext.LogicalGetData("key");Console.WriteLine(user == value1);// 異步線程執(zhí)行Task.Run(() =>{Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value2 = CallContext.LogicalGetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());Thread.Sleep(1000);value2 = CallContext.LogicalGetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());});// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");// 清理數(shù)據(jù)槽CallContext.FreeNamedDataSlot("key");var value3 = CallContext.LogicalGetData("key");Console.WriteLine(value3 == null ?"NULL" : (value3 == value1).ToString());}這段示例代碼的運行結(jié)果如下圖所示:

文章插圖
根據(jù)上圖所示的結(jié)果,基本可以得出以下三個結(jié)論:
1、FreeNamedDataSlot只能清除當(dāng)前線程的數(shù)據(jù)槽,不能清除子線程的數(shù)據(jù)槽;
2、LogicalSetData、LogicalGetData可用于在多線程環(huán)境下傳遞數(shù)據(jù);
3、FreeNamedDataSlot清除當(dāng)前線程的數(shù)據(jù)槽后,之前已經(jīng)運行的子任務(wù),不受影響;
測試3:LogicalGetData后修改傳遞的數(shù)據(jù)
在多線程環(huán)境下傳遞共享對象數(shù)據(jù),如果某個線程通過LogicalGetData后對其進行了修改又重新LogicalSetData會怎樣?
public void TestLogicalGetSetDataV2(){// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var user = new User(){Id = DateTime.Now.ToString(),Name = "Edison"};CallContext.LogicalSetData("key", user);var value1 = CallContext.LogicalGetData("key");Console.WriteLine(user == value1);// 異步線程同步執(zhí)行:加了.Wait()Task.Run(() =>{Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value2 = CallContext.LogicalGetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());CallContext.FreeNamedDataSlot("key");value2 = CallContext.LogicalGetData("key");Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());}).Wait();// 異步線程同步執(zhí)行:加了.Wait()Task.Run(() =>{Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value2 = CallContext.LogicalGetData("key") as User;Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString()); value2.Name = "Leo";CallContext.LogicalSetData("key", new User() { Id = DateTime.Now.ToString(), Name = "Jack" }); // 只影響當(dāng)前線程value2 = CallContext.LogicalGetData("key") as User;Console.WriteLine(value2 == null ?"NULL" : (value2 == value1).ToString());Console.WriteLine($"User.Name={value2.Name}");}).Wait();// 主線程執(zhí)行Console.WriteLine($"Current ThreadId={Thread.CurrentThread.ManagedThreadId}");var value3 = CallContext.LogicalGetData("key") as User;Console.WriteLine(value3 == null ?"NULL" : (value3 == value1).ToString());Console.WriteLine($"User.Name={value3.Name}");}上面示例代碼的運行結(jié)果如下圖所示:
文章插圖
根據(jù)上面的示例運行結(jié)果,我們又可以得到以下一些結(jié)論:
1、FreeNamedDataSlot只能清除當(dāng)前線程的數(shù)據(jù)槽
2、LogicalSetData只會存儲當(dāng)前線程以及子線程的數(shù)據(jù)槽;
3、LogicalGetData獲取的是當(dāng)前線程或父線程的數(shù)據(jù)槽對象,拿到的是對象的引用,因此如果對其進行修改,會影響父線程讀取的一致性,在關(guān)系型數(shù)據(jù)庫中也被稱為不可重復(fù)讀 。
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請您及時就醫(yī)或請專業(yè)人士給予相關(guān)指導(dǎo)!
「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對您有所幫助:- windows系統(tǒng)怎樣切換到蘋果系統(tǒng)
- 多線程上下文切換 多線程下的調(diào)用上下文 : CallContext
- 同城跑腿用啥軟件 同城配送跑腿軟件好急怎么切換城市?
- 蘋果雙系統(tǒng)如何切換-小白系統(tǒng)教程
- 蘋果windows雙系統(tǒng)切換教程
- 蘋果雙系統(tǒng)切換按哪個按鍵
- 雙系統(tǒng)怎么切換的步驟教程
- 電腦不斷黑屏和桌面切換 win10返回桌面模式
- 有氧無氧循環(huán)切換減肥 全方位快速減肥
- 電腦鍵盤基礎(chǔ)知識 電腦鍵盤功能基礎(chǔ)知識打字切換
