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();

興味深いことに、これはUnauthorizedAccessExceptionをにスローし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

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 に答える
1

残念ながら、FileSystemWatcherはディレクトリへのハンドルを取得しました。これは、ディレクトリが削除されても、PENDINGDELETEとマークされたディレクトリへのハンドルが残っていることを意味します。いくつかの実験を試しましたが、FileSystemWatcherのErrorイベントハンドラーを使用して、これがいつ発生するかを特定できるようです。

    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 に答える