最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#使用CallContext緩存線程數(shù)據(jù)

 更新時(shí)間:2022年05月13日 14:53:20   作者:springsnow  
這篇文章介紹了C#使用CallContext緩存線程數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、CallContext 概述

命名空間:System.Runtime.Remoting.Messaging

CallContext 用于提供與執(zhí)行代碼路徑一起傳送的屬性集,直白講就是:提供線程(多線程/單線程)代碼執(zhí)行路徑中數(shù)據(jù)傳遞的能力。

當(dāng)對(duì)另一個(gè) AppDomain 中的對(duì)象進(jìn)行遠(yuǎn)程方法調(diào)用時(shí),CallContext 類將生成一個(gè)與該遠(yuǎn)程調(diào)用一起傳播的 LogicalCallContext 實(shí)例。只有公開(kāi) ILogicalThreadAffinative 接口并存儲(chǔ)在 CallContext 中的對(duì)象被在 LogicalCallContext 中傳播到 AppDomain 外部。

CallContext成員

  • SetData:    存儲(chǔ)給定的對(duì)象并將其與指定名稱關(guān)聯(lián)。
  • GetData:    從CallContext中檢索具有指定名稱的對(duì)象    
  • LogicalSetData:    將給定的對(duì)象存儲(chǔ)在邏輯調(diào)用上下文,并將其與指定名稱關(guān)聯(lián)??捎糜诙嗑€程環(huán)境
  • LogicalGetData:     從邏輯調(diào)用上下文中檢索具有指定名稱的對(duì)象??捎糜诙嗑€程環(huán)境
  • FreeNamedDataSlot:    清空具有指定名稱的數(shù)據(jù)槽??捎糜诙嗑€程環(huán)境
  • HostContext屬性:     獲取或設(shè)置與當(dāng)前線程相關(guān)聯(lián)的主機(jī)上下文。在Web環(huán)境下等于System.Web.HttpContext.Current

GetData、SetData

  • 只能用于單線程環(huán)境,如果發(fā)生了線程切換,存儲(chǔ)的數(shù)據(jù)也會(huì)隨之丟失

  • 可以用于同一線程中的不同地方,傳遞數(shù)據(jù)

LogicalSetData、LogicalGetData

  • LogicalSetData、LogicalGetData可用于在多線程環(huán)境下傳遞數(shù)據(jù);
  • LogicalSetData只是存儲(chǔ)當(dāng)前線程以及子線程的數(shù)據(jù)槽
  • LogicalGetData獲取的是當(dāng)前線程或父線程的數(shù)據(jù)槽對(duì)象,拿到的是對(duì)象的引用
  • FreeNamedDataSlot清除當(dāng)前線程,之前已經(jīng)運(yùn)行子任務(wù),不受影響,不能清除子線程的數(shù)據(jù)槽;

二、 CallContext不跨線程傳播的方法:GetData、SetData

可以利用CallContext 實(shí)現(xiàn)單例,默認(rèn)情況下,CallContext 的數(shù)據(jù)不跨線程傳播。

1、在處理多組件共用Context時(shí)非常有用,比如常見(jiàn)的EF 可以將實(shí)例的DBEntity存儲(chǔ)在其中,可以一次訪問(wèn)只實(shí)例化一次,便于管理且不用多次實(shí)例訪問(wèn)對(duì)象

public static class DbContextHelper
{
    private static DbContext context = null;
    private const string SessionKey_DbContext = "Entities";
    public static DbContext GetDbContext()
    {
        if (CallContext.GetData(SessionKey_DbContext) == null)
        {
            CallContext.SetData(SessionKey_DbContext, new Entities());
        }
        return CallContext.GetData(SessionKey_DbContext) as Entities;
    }
}

2、類單例

void Main()
{
    MyAppContext.Current.FirstName = "a";
    Console.Write(MyAppContext.Current.FirstName);
}

public class MyAppContext
{
    const string contextKey = "MyAppContext:ContextKey";
    public string FirstName { get; set; }
    public static MyAppContext Current
    {
        get
        {
            if (CallContext.GetData(contextKey) == null)
            {
                CallContext.SetData(contextKey, new MyAppContext());
            }
            return CallContext.GetData(SessionKey_DbContext) as MyAppContext;
        }
    }
}

三、 CallContext跨線程傳播的方法:ILogicalSetData、LogicalGetData

要讓CallContext實(shí)現(xiàn)跨線程傳播,可以調(diào)用CallContext的靜態(tài)方法ILogicalSetData,或讓上下文類實(shí)現(xiàn)ILogicalThreadAffinative 接口。

線程本地存儲(chǔ)

線程池可能不會(huì)釋放使用過(guò)的線程,導(dǎo)致多次執(zhí)行之間可能共享數(shù)據(jù)(可以每次執(zhí)行前重置線程本地存儲(chǔ)的數(shù)據(jù))。

for (var i = 0; i < 10; i++)
{
    Thread.Sleep(10);

    Task.Run(() =>
    {
        var slot = Thread.GetNamedDataSlot("test");
        if (slot == null)
        {
            Thread.AllocateNamedDataSlot("test");
        }

        if (Thread.GetData(slot) == null)
        {
            Thread.SetData(slot, DateTime.Now.Millisecond);
        }

        Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + Thread.GetData(slot));
    });
}

結(jié)果

調(diào)用上下文

每次執(zhí)行的數(shù)據(jù)是完全隔離的,非常符合我們的期望。但是,如果我們期望調(diào)用期間又開(kāi)啟了一個(gè)子線程,如何讓子線程訪問(wèn)父線程的數(shù)據(jù)呢?這就需要使用到:“邏輯調(diào)用上下文”。

Console.WriteLine("測(cè)試:CallContext.SetData");
for (var i = 0; i < 10; i++)
{
    Thread.Sleep(10);

    Task.Run(() =>
    {
        if (CallContext.GetData("test") == null)
        {
            CallContext.SetData("test", DateTime.Now.Millisecond);
        }

        Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + CallContext.GetData("test"));
    });
}

結(jié)果

每次執(zhí)行的數(shù)據(jù)是完全隔離的,非常符合我們的期望。

邏輯調(diào)用上下文

如果我們期望調(diào)用期間又開(kāi)啟了一個(gè)子線程,如何讓子線程訪問(wèn)父線程的數(shù)據(jù)呢?這就需要使用到:“邏輯調(diào)用上下文”。

注意 ExecutionContext.SuppressFlow(); 和ExecutionContext.RestoreFlow();它們分別能阻止傳播和重置傳播,默認(rèn)是允許傳播的。

Console.WriteLine("測(cè)試:CallContext.SetData");
Task.Run(() =>
{
    CallContext.SetData("test", "段光偉");
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + CallContext.GetData("test"));

    Task.Run(() =>
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + CallContext.GetData("test"));
    });
});

Thread.Sleep(100);

Console.WriteLine("測(cè)試:CallContext.LogicalSetData");
Task.Run(() =>
{
    CallContext.LogicalSetData("test", "段光偉");
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + CallContext.LogicalGetData("test"));

    Task.Run(() =>
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + CallContext.LogicalGetData("test"));
    });

    ExecutionContext.SuppressFlow();
    Task.Run(() =>
    {
        Console.WriteLine("SuppressFlow 之后:" + CallContext.LogicalGetData("test"));
    });

    ExecutionContext.RestoreFlow();
    Task.Run(() =>
    {
        Console.WriteLine("RestoreFlow 之后:" + CallContext.LogicalGetData("test"));
    });
});

輸出

四、Web中的CallContext

HttpContext.Current(包括Session)的存儲(chǔ)是基于當(dāng)前線程的CallContext,在非請(qǐng)求處理線程(即其他線程)是無(wú)法獲取當(dāng)前HttpContext的(不跨線程傳播)。

到此這篇關(guān)于C#使用CallContext緩存線程數(shù)據(jù)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#驗(yàn)證兩個(gè)QQ頭像相似度的示例代碼

    C#驗(yàn)證兩個(gè)QQ頭像相似度的示例代碼

    這篇文章主要介紹了c#驗(yàn)證兩個(gè)QQ頭像相似度,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • C# Linq延遲查詢的執(zhí)行實(shí)例代碼

    C# Linq延遲查詢的執(zhí)行實(shí)例代碼

    這篇文章主要介紹了C# Linq延遲查詢執(zhí)行的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • C# WinForm捕獲未處理的異常實(shí)例解析

    C# WinForm捕獲未處理的異常實(shí)例解析

    這篇文章主要介紹了C# WinForm捕獲未處理的異常,包括了常見(jiàn)的未捕獲的異常、UI線程異常、非UI線程異常等,非常實(shí)用,需要的朋友可以參考下
    2014-09-09
  • C#實(shí)現(xiàn)對(duì)圖片文件的壓縮、裁剪操作實(shí)例

    C#實(shí)現(xiàn)對(duì)圖片文件的壓縮、裁剪操作實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)對(duì)圖片文件的壓縮、裁剪操作,較為詳細(xì)的介紹了操作過(guò)程中用到的相關(guān)類文件及具體的操作步驟,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-09-09
  • C#?WPF?ListBox?動(dòng)態(tài)顯示圖片功能

    C#?WPF?ListBox?動(dòng)態(tài)顯示圖片功能

    這篇文章主要介紹了C#?WPF?ListBox?動(dòng)態(tài)顯示圖片,處理過(guò)程分為前臺(tái)代碼和后臺(tái)代碼,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • C#簡(jiǎn)單遍歷指定文件夾中所有文件的方法

    C#簡(jiǎn)單遍歷指定文件夾中所有文件的方法

    這篇文章主要介紹了C#簡(jiǎn)單遍歷指定文件夾中所有文件的方法,結(jié)合實(shí)例形式分析了文件夾與文件遍歷的技巧,并附帶說(shuō)明了文件與文件夾操作的常用函數(shù),需要的朋友可以參考下
    2016-06-06
  • C#內(nèi)存管理CLR深入講解(下篇)

    C#內(nèi)存管理CLR深入講解(下篇)

    本文詳細(xì)講解了C#內(nèi)存管理CLR的內(nèi)存分配和對(duì)大對(duì)象回收,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • C#調(diào)用Rar文件及獲取Rar返回值的方法

    C#調(diào)用Rar文件及獲取Rar返回值的方法

    這篇文章主要介紹了C#調(diào)用Rar文件及獲取Rar返回值的方法,實(shí)例分析了C#調(diào)用rar文件實(shí)現(xiàn)文件的壓縮與解壓相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C#監(jiān)測(cè)IPv4v6網(wǎng)速及流量的實(shí)例代碼

    C#監(jiān)測(cè)IPv4v6網(wǎng)速及流量的實(shí)例代碼

    這篇文章主要介紹了C#監(jiān)測(cè)IPv4v6網(wǎng)速及流量的實(shí)例代碼,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 淺談Java與C#的一些細(xì)微差別

    淺談Java與C#的一些細(xì)微差別

    說(shuō)起C#和Java這兩門語(yǔ)言(語(yǔ)法,數(shù)據(jù)類型 等),個(gè)人以為,大概有90%以上的相似,甚至可以認(rèn)為幾乎一樣。但是在工作中,我也發(fā)現(xiàn)了一些細(xì)微的差別
    2013-11-11

最新評(píng)論

闻喜县| 仪陇县| 铜山县| 济宁市| 屏南县| 株洲县| 项城市| 合肥市| 太白县| 兴文县| 九台市| 唐河县| 钦州市| 富源县| 文山县| 阜新市| 漠河县| 故城县| 金寨县| 慈溪市| 茂名市| 河池市| 泾阳县| 孝昌县| 灵寿县| 合水县| 新平| 南宫市| 探索| 望谟县| 平罗县| 吉首市| 长丰县| 西贡区| 富宁县| 平顶山市| 福泉市| 义马市| 海盐县| 三河市| 华坪县|