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

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

為什么不能在lock語句的主體內(nèi)使用'await'運(yùn)算符?

為什么不能在lock語句的主體內(nèi)使用'await'運(yùn)算符?

慕后森 2019-10-15 09:24:16
鎖定語句中不允許使用C#(.NET Async CTP)中的await關(guān)鍵字。從MSDN:等待表達(dá)式不能用于同步函數(shù),查詢表達(dá)式,異常處理語句的catch或finally塊,鎖語句的塊或不安全的上下文中。我認(rèn)為由于某種原因,對于編譯器團(tuán)隊(duì)而言,這既困難又不可能。我嘗試了using語句:class Async{    public static async Task<IDisposable> Lock(object obj)    {        while (!Monitor.TryEnter(obj))            await TaskEx.Yield();        return new ExitDisposable(obj);    }    private class ExitDisposable : IDisposable    {        private readonly object obj;        public ExitDisposable(object obj) { this.obj = obj; }        public void Dispose() { Monitor.Exit(this.obj); }    }}// example usageusing (await Async.Lock(padlock)){    await SomethingAsync();}但是,這無法正常工作。在ExitDisposable.Dispose中對Monitor.Exit的調(diào)用似乎無限期地(大部分時(shí)間)阻塞,導(dǎo)致死鎖,因?yàn)槠渌€程試圖獲取該鎖。我懷疑我的工作不可靠,而鎖語句中不允許使用await語句的原因與某種原因有關(guān)。有誰知道為什么鎖語句體內(nèi)不允許等待?
查看完整描述

3 回答

?
千巷貓影

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

我認(rèn)為由于某種原因,對于編譯器團(tuán)隊(duì)而言,這既困難又不可能。


不,實(shí)施起來并非沒有困難或不可能,您自己實(shí)施的事實(shí)就證明了這一事實(shí)。相反,這是一個(gè)非常糟糕的主意,因此我們不允許這樣做,以防止您犯此錯(cuò)誤。


在DisposeDisposable.Dispose中對Monitor.Exit的調(diào)用似乎無限期地(大部分時(shí)間)阻塞,導(dǎo)致死鎖,因?yàn)槠渌€程試圖獲取該鎖。我懷疑我的工作不可靠,而鎖語句中不允許使用await語句的原因與某種原因有關(guān)。


正確,您已經(jīng)發(fā)現(xiàn)我們將其設(shè)為非法的原因。在鎖內(nèi)部等待等待是產(chǎn)生死鎖的秘訣。


我敢肯定,您會(huì)明白為什么:在await將控制權(quán)返回給調(diào)用方與方法恢復(fù)之間的這段時(shí)間內(nèi),任意代碼都會(huì)運(yùn)行。那個(gè)任意代碼可能會(huì)取出產(chǎn)生鎖順序倒置的鎖,從而導(dǎo)致死鎖。


更糟糕的是,代碼可能會(huì)在另一個(gè)線程上恢復(fù)(在高級方案中;通常您會(huì)在執(zhí)行等待的線程上再次接聽,但不一定),在這種情況下,解鎖將解鎖與所用線程不同的線程上的鎖開鎖。這是一個(gè)好主意嗎?沒有。


我注意到,出于相同的原因,對a進(jìn)行yield return內(nèi)部操作也是“最差的做法” lock。這樣做是合法的,但我希望我們將其定為非法。我們不會(huì)為“等待”犯同樣的錯(cuò)誤。


查看完整回答
反對 回復(fù) 2019-10-15
?
藍(lán)山帝景

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

使用SemaphoreSlim.WaitAsync方法。


 await mySemaphoreSlim.WaitAsync();

 try {

     await Stuff();

 } finally {

     mySemaphoreSlim.Release();

 }


查看完整回答
反對 回復(fù) 2019-10-15
?
慕絲7291255

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

基本上,這將是錯(cuò)誤的事情。


有兩個(gè)方面,這可以實(shí)現(xiàn):


保持鎖,只在塊的末尾釋放它。

這是一個(gè)非常糟糕的主意,因?yàn)槟恢喇惒讲僮鲗⒒ㄙM(fèi)多長時(shí)間。您只應(yīng)在最短時(shí)間內(nèi)握住鎖。這也可能是不可能的,因?yàn)榫€程擁有一個(gè)鎖,而不是一個(gè)方法-并且您甚至可能沒有在同一線程上執(zhí)行其余的異步方法(取決于任務(wù)調(diào)度程序)。


釋放等待中的鎖,并在等待返回時(shí)重新獲取它。

這違反了IMO最小原則,在IMO中,異步方法的行為應(yīng)與等效的同步代碼盡可能接近-除非您Monitor.Wait在鎖塊中使用,否則您希望在該區(qū)塊的持續(xù)時(shí)間內(nèi)擁有該鎖。


因此,這里基本上有兩個(gè)相互競爭的需求-您不應(yīng)該在這里嘗試第一個(gè),而如果您想采用第二種方法,則可以通過用await表達(dá)式分隔兩個(gè)分開的鎖塊來使代碼更清晰:


// Now it's clear where the locks will be acquired and released

lock (foo)

{

}

var result = await something;

lock (foo)

{

}

因此,通過禁止您等待鎖塊本身,該語言迫使您考慮自己真正想做的事情,并在編寫的代碼中使選擇更清晰。


查看完整回答
反對 回復(fù) 2019-10-15
  • 3 回答
  • 0 關(guān)注
  • 3341 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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