我正在尝试使用C#File.Delete API删除Windows上的文件。 https://msdn.microsoft.com/en-us/library/system.io.file.delete(v=vs.110).aspx 我间歇地使用此API面临UnauthorizedAccessException。实际上,多个进程/线程使用此文件作为此文件上的File.Open锁。如果文件正在使用中,我希望从底层的Windows代码中抛出IOException,但有时我会看到UnauthorizedAccessException。执行此操作的过程具有适当的权限,并且在大多数情况下都适用,但随机我遇到了此问题。
更多信息: 我用作锁的文件的扩展名是.lck,它总是为空的。它仅用于File.Open API的锁定目的。 文档说如果文件是正在使用的可执行文件,也会抛出UnauthorizedAccessException。
问题: 是否有可能将.lck视为可执行文件并抛出UnauthorizedAccessException?
UnauthorizedAccessException的原因是什么,因为如果正在使用该文件,我期望IOException?
答案 0 :(得分:0)
File.Delete
函数在内部调用Win32 API的DeleteFile函数。
文档说:
如果应用程序尝试删除不存在的文件,则DeleteFile函数将失败并显示ERROR_FILE_NOT_FOUND。 如果文件是只读文件,则函数将失败,并显示ERROR_ACCESS_DENIED 。
及以下:
DeleteFile函数在关闭时标记要删除的文件。 因此,在关闭文件的最后一个句柄之前不会发生文件删除。随后调用CreateFile以打开文件失败并显示ERROR_ACCESS_DENIED 。
ERROR_ACCESS_DENIED
代码导致UnauthorizedAccessException
。
因此文件上至少有一个写句柄处于活动状态。
通常,使用文件句柄来同步进程是个坏主意。解决此问题的更好方法是使用名为EventWaitHandle
或命名为Mutex
(请参阅Synchronizing 2 processes using interprocess synchronizations objects - Mutex or AutoResetEvent获取mor信息)
例如,在 Process1 中执行:
while (true)
{
using (var mutex = new Mutex(false, "THIS_IS_THE_UNIQUE_NAME_OF_THE_MUTEX"))
{
if (!mutex.WaitOne(0))
{
Console.WriteLine($"Process {Process.GetCurrentProcess().Id} waits");
mutex.WaitOne();
}
Console.Write($"Process {Process.GetCurrentProcess().Id} has entered protected area...");
Thread.Sleep(1000); // simulate work
Console.WriteLine("and is about to leave!");
mutex.ReleaseMutex();
}
}
和 Process2 :
using (var mutex = new Mutex(false, "THIS_IS_THE_UNIQUE_NAME_OF_THE_MUTEX"))
{
mutex.WaitOne();
Thread.Sleep(5000); // simulate work on different process
mutex.ReleaseMutex();
}
Process1 将等待 Process2 释放互斥锁,反之亦然。