1

以下 C# 代码有时会在 "File.WriteAllText("test_a.cmd", "timeout 15")" 行失败,有谁知道为什么以及如何解决它?谢谢。

        for (int i = 0; i < 100; i++)
        {
            File.WriteAllText("test_a.cmd", "rem timeout 1");
            var p = Process.Start("test_a.cmd");

            p.WaitForExit();
            p.Dispose();
            p = null;

            //GC.Collect();
            //GC.WaitForPendingFinalizers();

            File.Delete("test_a.cmd");

            // Somtetimes it causes System.UnauthorizedAccessException: Access to the path 'XXX\test_a.cmd' is denied.
            File.WriteAllText("test_a.cmd", "timeout 15");
        }
4

2 回答 2

2

还有另一个进程通过删除共享打开了文件。这允许您的 File.Delete() 调用成功。但不是随后的 File.WriteAllText()。因为删除后该文件仍然存在。在其他进程关闭文件的句柄之前,它不会消失。像这样在文件仍处于不确定状态时覆盖文件的任何尝试都将失败,并出现“拒绝访问”错误。

这就是在多任务操作系统上运行程序的变幻莫测,其他进程可能对您操作的文件感兴趣。在大多数 Windows 安装中,这样的过程总是有一个很好的候选者,禁用你的防病毒程序,看看是否能解决问题。

除了睡一会儿再试一次之外,还有一种体面的方法可以最大程度地减少损失。您可以重命名文件,这样您遇到此异常的几率要低得多:

File.Delete("test_a.cmd.bak");
File.Move("test_a.cmd", "test_a.cmd.bak");
for (int attempt = 0; ; ++attempt) {
    try {
       File.WriteAllText("test_a.cmd", "timeout 15");
       break;
    }
    catch (System.UnauthorizedAccessException ex) {
       if (attempt > 10) throw;
       System.Threading.Thread.Sleep(1000);
    }
}
try {
    File.Delete("test_a.cmd.bak");
}
catch (Exception ex) {}
于 2013-10-21T09:56:43.000 回答
0

由于 File.WriteAllText() 创建/覆盖文件,因此不需要调用 Delete。事实上,这可能就是导致您的问题的原因。

所以,我的解决方案是:

  • 远程文件.删除
  • 在最后一个 WriteAllText 之前添加 Thread.Sleep(100)

睡眠部分是允许 Windows 进行处理,这基本上是导致您的异常的原因。

于 2013-10-21T08:30:25.200 回答