我刚看到这个问题:Is it safe to use static methods on File class in C#?。总结一下,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集中到一个同步的线程安全类(或者删除文件以支持其他东西)的问题。我读了两个答案,当我即将向其中一个人投票时,我看到那些用户是谁,我想 h * 并停止了。
我会引用它们(然后请参阅原始答案以获取更多背景信息)。
对于本OP段:
我猜测文件读取操作有时在写入操作发生之前没有关闭文件[...]
答案是:
正确。文件系统不支持原子更新[...]使用FileStream没有帮助[...]文件里面没有魔法。它只是为了您的方便而使用FileStream包装。
但是,我没有看到对原子操作(读取+后续写入)和并行的预期(由于部分重叠的多线程请求)可能导致并发访问。即使是原子 I / O操作(读取+写入)也会出现完全相同的问题。确定FileStream
可能是异步的,但不是File.ReadAllText()
和File.WriteAllText()
使用它的方式。
另一个答案让我更加困惑,它说:
虽然根据文档,该方法保证文件句柄被关闭,但即使引发异常,也不能保证在方法返回之前发生关闭的时间:关闭可以异步完成。
什么? MSDN说方法将打开,读取和关闭文件(如果是异常)。这种方法是否有可能异步关闭文件? OS会推迟CloseHandle()
吗?在哪些情况下?为什么呢?
简而言之:它只是一种误解还是CloseHandle()
是异步的?我错过了非常重要的内容?
答案 0 :(得分:4)
如果查看CloseHandle
文档,它会说明打开句柄的每个方法都有关于如何关闭它的说明:
创建这些对象的函数的文档 表示完成后应使用CloseHandle 对象,以及之后对象的挂起操作会发生什么 句柄已关闭。通常,CloseHandle会使句柄无效 指定的对象句柄,递减对象的句柄计数,和 执行对象保留检查。在对象的最后一个句柄之后 关闭后,对象将从系统中删除。
当您查看CreateFile
文档时,就会这样说:
当应用程序使用返回的对象句柄完成时 CreateFile,使用CloseHandle函数关闭句柄。 这不是 只释放系统资源,但可以对事物产生更广泛的影响 比如共享文件或设备并将数据提交到磁盘。
我会发现,CloseHandle
会产生底层句柄被关闭而异步保留文件以进行其他检查,这一点很奇怪。这会削弱操作系统对调用者的许多保证,并且会成为许多错误的来源。
答案 1 :(得分:1)
你问题中的前两个引号不应该是相关的。完成File.*
后,或关闭FileStream
时,文件会立即解锁。从来没有任何“挥之不去”。如果有,你再也无法安全地访问同一个文件而不重新启动。
可以回答假定问题中的代码并行运行多次。如果没有,该代码显然是安全的。
但是我没有看到任何原子操作的期望......即使是原子I / O操作(读/写)也会有完全相同的问题。
这是真的。我不知道为什么我在答案中对此作了陈述(但这是正确的。只是不相关)。
在方法返回之前不能保证关闭的时间:关闭可以异步完成。
我不知道他为什么这么说,因为在我能想到的任何情况下都不正确。关闭手柄会立即生效。
我认为你对这种情况的理解是完全准确的。显然,我们的答案不清楚,有些误导......抱歉。