第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

ExecutionContext 不會(huì)從異步方法向上流動(dòng)調(diào)用堆棧

ExecutionContext 不會(huì)從異步方法向上流動(dòng)調(diào)用堆棧

C#
慕姐8265434 2022-11-22 16:01:43
考慮以下代碼:private static async Task Main(string[] args){    await SetValueInAsyncMethod();    PrintValue();    await SetValueInNonAsyncMethod();    PrintValue();}private static readonly AsyncLocal<int> asyncLocal = new AsyncLocal<int>();private static void PrintValue([CallerMemberName] string callingMemberName = ""){    Console.WriteLine($"{callingMemberName}: {asyncLocal.Value}");}private static async Task SetValueInAsyncMethod(){    asyncLocal.Value = 1;    PrintValue();    await Task.CompletedTask;}private static Task SetValueInNonAsyncMethod(){    asyncLocal.Value = 2;    PrintValue();    return Task.CompletedTask;}如果您在 .NET 4.7.2 控制臺(tái)應(yīng)用程序中運(yùn)行此代碼,您將獲得以下輸出:SetValueInAsyncMethod: 1Main: 0SetValueInNonAsyncMethod: 2Main: 2我確實(shí)理解輸出的差異源于這樣一個(gè)事實(shí),即SetValueInAsyncMethod它不是真正的方法,而是一個(gè)執(zhí)行的狀態(tài)機(jī),它在內(nèi)部AsyncTaskMethodBuilder捕獲并且只是一個(gè)常規(guī)方法。ExecutionContextSetValueInNonAsyncMethod但即使有了這種理解,我仍然有一些問題:這是錯(cuò)誤/缺失的功能還是有意的設(shè)計(jì)決定?在編寫依賴于 的代碼時(shí),我是否需要擔(dān)心這種行為AsyncLocal?比如說,我想編寫我的TransactionScope-wannabe,它通過等待點(diǎn)來傳輸一些環(huán)境數(shù)據(jù)。AsyncLocal這里夠了嗎?當(dāng)歸結(jié)為在整個(gè)“邏輯代碼流”中保留值時(shí),在 .NET 中是否還有其他替代方法AsyncLocal和CallContext.LogicalGetData/ ?CallContext.LogicalSetData
查看完整描述

2 回答

?
慕尼黑5688855

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超2個(gè)贊

這是錯(cuò)誤/缺失的功能還是有意的設(shè)計(jì)決定?

這是一個(gè)有意的設(shè)計(jì)決定。具體來說,async狀態(tài)機(jī)為其邏輯上下文設(shè)置“寫時(shí)復(fù)制”標(biāo)志。

與此相關(guān)的是所有同步方法都屬于它們最近的祖先async方法。

在編寫依賴于 AsyncLocal 的代碼時(shí),我是否需要擔(dān)心這種行為?比如說,我想編寫我的 TransactionScope-wannabe,它通過等待點(diǎn)傳輸一些環(huán)境數(shù)據(jù)。這里 AsyncLocal 夠用嗎?

像這樣的大多數(shù)系統(tǒng)都AsyncLocal<T>結(jié)合了IDisposable清除AsyncLocal<T>值的模式。組合這些模式可確保它適用于同步或異步代碼。AsyncLocal<T>如果消費(fèi)代碼是一個(gè)async方法,它自己會(huì)工作得很好;與它一起使用IDisposable確保它可以同時(shí)使用async和同步方法。

當(dāng)涉及到在整個(gè)“邏輯代碼流”中保留值時(shí),.NET 中的 AsyncLocal 和 CallContext.LogicalGetData / CallContext.LogicalSetData 是否還有其他替代方案?

不。


查看完整回答
反對(duì) 回復(fù) 2022-11-22
?
拉丁的傳說

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊

這對(duì)我來說似乎是一個(gè)有意的決定。


正如您已經(jīng)知道的那樣,它SetValueInAsyncMethod被編譯成一個(gè)隱式捕獲當(dāng)前 ExecutionContext 的狀態(tài)機(jī)。當(dāng)您更改AsyncLocal-variable 時(shí),該更改不會(huì)“流”回調(diào)用函數(shù)。相反,SetValueInNonAsyncMethod它不是異步的,因此沒有編譯成狀態(tài)機(jī)。因此,不會(huì)捕獲 ExecutionContext 并且對(duì)AsyncLocal-variables 的任何更改對(duì)調(diào)用者都是可見的。


如果您出于任何原因需要它,您也可以自己捕獲 ExecutionContext:


private static Task SetValueInNonAsyncMethodWithEC()

{

    var ec = ExecutionContext.Capture(); // Capture current context into ec

    ExecutionContext.Run(ec, _ => // Use ec to run the lambda

    {

        asyncLocal.Value = 3;

        PrintValue();

    });

    return Task.CompletedTask;

}

這將輸出值 3,而 Main 將輸出 2。


當(dāng)然,簡(jiǎn)單地轉(zhuǎn)換SetValueInNonAsyncMethod為異步讓編譯器為您做這件事要容易得多。


關(guān)于使用AsyncLocal(或就此而言CallContext.LogicalGetData)的代碼,重要的是要知道更改調(diào)用的異步方法(或任何捕獲的 ExecutionContext)中的值不會(huì)“回流”。但您當(dāng)然仍然可以訪問和修改AsyncLocal,只要您不重新分配它即可。


查看完整回答
反對(duì) 回復(fù) 2022-11-22
  • 2 回答
  • 0 關(guān)注
  • 110 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)