2

考虑这段代码:

string dir = Environment.CurrentDirectory + @"\a";
Directory.CreateDirectory(dir);
FileSystemWatcher watcher = new FileSystemWatcher(dir);
watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Deleting " + dir);
Directory.Delete(dir, true);
if (Directory.Exists(dir))
{
    Console.WriteLine("Getting dirs of " + dir);
    Directory.GetDirectories(dir);
}
Console.ReadLine();

有趣的是,这会在Directory.GetDirectories(dir).

删除监视的目录返回没有错误,但 Directory.Exists() 仍然返回 true 并且该目录仍然列出。此外,访问该目录会为任何程序产生“拒绝访问”。一旦带有 FileSystemWatcher 的 .NET 应用程序退出,目录就会消失。

如何在允许正确删除目录的同时观看目录?

4

4 回答 4

5

您实际上确实删除了该目录。但是直到关闭引用它的最后一个句柄,该目录才会从文件系统中物理删除。在两者之间打开它的任何尝试(就像您对 GetDirectories 所做的那样)都将失败并出现拒绝访问错误。

文件也存在相同的机制。查看 FileShare.Delete

于 2010-08-08T10:56:14.537 回答
2

试试这条线:

 if (new DirectoryInfo(dir).Exists)

代替:

if (Directory.Exists(dir))
于 2010-08-08T13:06:00.860 回答
1

不幸的是,FileSystemWatcher 已经获取了目录的句柄,这意味着当目录被删除时,仍然有一个指向标记为 PENDING DELETE 的目录的句柄。我尝试了一些实验,似乎您可以使用 FileSystemWatcher 中的错误事件处理程序来确定何时发生这种情况。

    public myClass(String dir)
    {
        mDir = dir;
        Directory.CreateDirectory(mDir);

        InitFileSystemWatcher();

        Console.WriteLine("Deleting " + mDir);
        Directory.Delete(mDir, true);
    }
    private FileSystemWatcher watcher;

    private string mDir;

    private void MyErrorHandler(object sender, FileSystemEventArgs args)
    {
        // You can try to recreate the FileSystemWatcher here
        try
        {
            mWatcher.Error -= MyErrorHandler;
            mWatcher.Dispose();
            InitFileSystemWatcher();
        }
        catch (Exception)
        {
            // a bit nasty catching Exception, but you can't do much
            // but the handle should be released now 
        }
        // you might not be able to check immediately as your old FileSystemWatcher
        // is in your current callstack, but it's a start.
    }

    private void InitFileSystemWatcher()
    {
        mWatcher = new FileSystemWatcher(mDir);
        mWatcher.IncludeSubdirectories = false;
        mWatcher.EnableRaisingEvents = true;
        mWatcher.Error += MyErrorHandler;
    }
于 2014-10-27T17:26:57.533 回答
1

您应该使用 FileSystemInfo.Refresh。在 .Refresh() .Exists 之后显示正确的结果:

    var dir = new DirectoryInfo(path);
    // delete dir in explorer
    System.Diagnostics.Debug.Assert(dir.Exists); // true
    dir.Refresh();
    System.Diagnostics.Debug.Assert(!dir.Exists); // false
于 2012-07-11T18:30:36.393 回答