Tom*_* K. 9 c# multithreading asynchronous race-condition async-await
我只是想知道下面的代码中是否出现竞争条件:
int readingFiles;
async Task<string> ReadFile (string file)
{
++readingFiles;
var text = await Stream.ReadFileAsync(file);
--readingFiles;
return text;
}
Run Code Online (Sandbox Code Playgroud)
如果线程池线程执行ReadFile方法,则readFiles将由两个不同的线程访问,而readingFiles变量不受任何同步惯用法的保护.
这意味着对于执行"--readingFiles"的其他线程,readFiles的第一次更新不应该是可见的.但是,在"--readingFiles"之后,我从未见过readFiles等于-1.我检查同一个线程是否使用Thread.CurrentThread执行++和 - 操作.在大多数情况下,它不是同一个线程,我仍然没有看到readingFiles为-1.
即使存在竞争条件且readingFiles不易变,为什么我不能看到这种竞争条件的影响?
Ste*_*ary 11
这里没有竞争条件..NET运行时将插入适当的内存屏障.
另请参阅以下评论:http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx
是的,当任务排队时以及任务执行的开始/结束时,TPL包含适当的障碍,以使值适当地可见.
这里可能会发生很多事情。
首先,您正在运行哪种可执行文件?当 Await 触发时,它使用当前的同步上下文,因此您等待的代码可能会序列化为 1 个 UI 线程。
此外,由于变量周围没有内存屏障/易失性保护,因此您的线程可能会读取单独缓存的值(如 @Spo1ler 在他的帖子中提到的)
此外,线程池可能会选择在同一个线程上运行您的两个请求(这样做是在它的权利范围内 - 您让 .net/windows 决定何时以及如何分配线程)
但最重要的是,您确实应该通过同步或互锁操作来保护对变量的访问。