使用System.IO.File帮助方法的“顺序”文件I / O是否安全?

我刚看到这个问题: 在C#中对File类使用静态方法是否安全? 。 总结一下,OP有一个IOException因为这个ASP.NET代码片段中正在使用该文件:

 var text= File.ReadAllText("path-to-file.txt"); // Do something with text File.WriteAllText("path-to-file.txt"); 

我的第一个想法是,由于多个ASP.NET重叠请求,这是一个简单的并发访问问题。 我要解决的问题是将I / O集中到同步的线程安全类中(或者删除文件以支持其他东西)。 我读了两个答案,当我即将向其中一个人投票时,我看到那些用户是谁,我想到了什么,并且停止了。

我会引用它们两者(然后请参阅原始答案以获取更多背景信息)。

对于这个OP段:

我猜测文件读取操作有时不会在写入操作发生之前关闭文件[…]

答案说:

正确。 文件系统不支持primefaces更新[…]使用FileStream没有帮助[…]文件里面没有魔法。 它只是为了您的方便而使用FileStream包装。

但是我没有看到任何期望primefaces操作(读取+后续写入)和并行 (因为部分重叠的multithreading请求)可能导致并发访问。 即使是primefaces I / O操作(读/写)也会有完全相同的问题。 OK FileStream 可能是异步的,但不是File.ReadAllText()File.WriteAllText()使用它的方式。

另一个答案让我更加困惑 ,它说:

虽然根据文档,该方法保证文件句柄被关闭,但即使引发exception,也不能保证在方法返回之前发生关闭的时间:关闭可以异步完成。

什么? MSDN说方法将打开,读取和关闭文件(如果是exception)。 这种方法是否有可能异步关闭文件? OS会推迟CloseHandle()吗? 在哪些情况下? 为什么?

简而言之:它只是一个误解还是CloseHandle()是异步的? 我错过了一些非常重要的东西?

你问题中的前两个引号不应该是相关的。 完成File.*或关闭FileStream ,文件立即解锁。 从来没有任何“挥之不去”。 如果有,你再也无法安全地访问同一个文件而不重新启动。

可以回答假定问题中的代码并行运行多次。 如果没有,该代码显然是安全的。

但是我没有看到任何对primefaces操作的期望……即使是primefacesI / O操作(读/写)也会有完全相同的问题。

确实如此。 我不知道为什么我在答案中对此作了陈述(但这是正确的。只是不相关)。

在方法返回之前不能保证关闭的时间:关闭可以异步完成。

我不知道他为什么这么说,因为在我能想到的任何情况下都不正确。 关闭手柄会立即生效。


我认为你对这种情况的理解是完全准确的。 显然,我们的答案不清楚,有些误导……抱歉。

如果查看CloseHandle文档,它会指出打开句柄的每个方法都有关于如何关闭它的描述:

创建这些对象的函数的文档指示在完成对象时应该使用CloseHandle,以及在句柄关闭后对象上的挂起操作会发生什么。 通常,CloseHandle使指定的对象句柄无效,减少对象的句柄计数,并执行对象保留检查。 关闭对象的最后一个句柄后,将从系统中删除该对象。

当您查看CreateFile文档时,它就是这样说的:

使用CreateFile返回的对象句柄完成应用程序后,使用CloseHandle函数关闭句柄。 这不仅可以释放系统资源,还可以对共享文件或设备以及将数据提交到磁盘等方面产生更广泛的影响。

我会发现,特殊的是, CloseHandle会产生底层句柄被关闭,同时异步保留文件以进行额外的检查。 这会削弱操作系统对调用者的许多保证,并且会成为许多错误的来源。