[英]Race Condition in Async/Await Code
我只是想知道下面的代碼中是否出現競爭條件:
int readingFiles;
async Task<string> ReadFile (string file)
{
++readingFiles;
var text = await Stream.ReadFileAsync(file);
--readingFiles;
return text;
}
如果線程池線程執行ReadFile方法,則readFiles將由兩個不同的線程訪問,而readingFiles變量不受任何同步慣用法的保護。
這意味着對於執行“--readingFiles”的其他線程,readFiles的第一次更新不應該是可見的。 但是,在“--readingFiles”之后,我從未見過readFiles等於-1。 我檢查同一個線程是否使用Thread.CurrentThread執行++和 - 操作。 在大多數情況下,它不是同一個線程,我仍然沒有看到readingFiles為-1。
即使存在競爭條件且readingFiles不易變,為什么我不能看到這種競爭條件的影響?
這里沒有競爭條件。 .NET運行時將插入適當的內存屏障。
另請參閱以下評論: http : //blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx
是的,當任務排隊時以及任務執行的開始/結束時,TPL包含適當的障礙,以使值適當地可見。
這里有許多事情可以發生。
首先,你運行什么樣的可執行文件? 當Await觸發時,它使用當前的同步上下文,因此您等待的代碼可能被序列化為1個UI線程。
此外,由於變量周圍沒有內存屏障/波動保護,您的線程可能正在讀取單獨緩存的值(如@ Spo1ler在其帖子中所述)
此外,線程池可能選擇在同一個線程上運行您的請求(這是在其權限范圍內 - 您讓.net / windows決定何時以及如何分配線程)
但最重要的是,您確實應該通過同步或互鎖操作來保護對變量的訪問。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.