![](/img/trans.png)
[英]How can i use FileSystemWatcher to watch directory if directory not exist?
[英]How can I watch a directory with a FileSystemWatcher and still allow for it to be properly deleted?
考虑以下代码:
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)
上抛出UnauthorizedAccessException。
删除监视的目录会返回而不会出现错误,但Directory.Exists()仍然返回true并且仍然列出该目录。 此外,访问目录会为任何程序产生“拒绝访问”。 一旦带有FileSystemWatcher的.NET应用程序退出目录就消失了。
如何在仍允许正确删除目录的同时观看目录?
你确实删除了该目录。 但是,在关闭引用它的最后一个句柄之前,不会从文件系统中物理删除该目录。 任何在中间打开它的尝试(就像你使用GetDirectories一样)都将失败并出现拒绝访问错误。
文件存在相同的机制。 查看FileShare.Delete
试试这一行:
if (new DirectoryInfo(dir).Exists)
代替:
if (Directory.Exists(dir))
你应该使用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
不幸的是,FileSystemWatcher占用了目录,这意味着当删除目录时,仍然有一个标记为PENDING DELETE的目录句柄。 我尝试了一些实验,似乎你可以使用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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.