【发布时间】:2017-02-24 22:22:31
【问题描述】:
我设置了一个文件系统观察程序来处理/移动转储到某个位置的文件。前几次我运行它,它运行良好,然后它随机停止检测文件更改。什么可能导致这种情况?我将在下面发布我的代码。
protected override void OnStart(string[] args)
{
fileSystemWatcher1.Path = Config.ToString("WATCHPATH");
//ignore subfolder changes (error and archive)
fileSystemWatcher1.IncludeSubdirectories = false;
//add event handlers
fileSystemWatcher1.Changed += new FileSystemEventHandler(OnChanged);
fileSystemWatcher1.Created += new FileSystemEventHandler(OnChanged);
fileSystemWatcher1.Deleted += new FileSystemEventHandler(OnDeleted);
fileSystemWatcher1.Renamed += new RenamedEventHandler(OnRenamed);
//begin watching
fileSystemWatcher1.EnableRaisingEvents = true;
}
void OnChanged(object sender, FileSystemEventArgs e)
{
try
{
FileAttributes attr;
try
{
attr = File.GetAttributes(e.FullPath);
}
catch (FileNotFoundException fnfEx)
{
//this is here because after you move the file to the archive folder
//it triggers a change, and can't find the old file. This ignores changes
//in subdirectories after moves from main drop folder
return;
}
//this checks if a path is a directory which eliminates circular events being triggered
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
return;
}
FileProcessor fp = new FileProcessor();
fp.Process(e.FullPath);
DirectoryInfo parentDirectory = System.IO.Directory.GetParent(e.FullPath);
string archivePath = parentDirectory.FullName + "\\Archive\\" + Settings._sys.User.UserID + "_" + DateTime.Today.Date.ToString("ddMMMMyyyy") + "_" + e.Name;
if (!Directory.Exists(parentDirectory.FullName + "\\Archive"))
{
//create archive directory
Directory.CreateDirectory(parentDirectory.FullName + "\\Archive");
}
//appends number to file if the filename already exists
if (File.Exists(archivePath))
{
string pathOnly = archivePath.Substring(0, archivePath.LastIndexOf('\\'));
string[] files = Directory.GetFiles(pathOnly, Path.GetFileNameWithoutExtension(archivePath) + "*" + Path.GetExtension(archivePath));
int x = files.Max(f => GetFileNumber(f)) + 1;
string fileNameNoExt = e.Name.Substring(0, e.Name.IndexOf("."));
archivePath = parentDirectory.FullName + "\\Archive\\" + Settings._sys.User.UserID + "_" + DateTime.Today.Date.ToString("ddMMMMyyyy") + "_" + fileNameNoExt + "_" + x.ToString() + ".xlsx";
}
fileSystemWatcher1.EnableRaisingEvents = false;
try
{
while (IsFileReady(e.FullPath) != true)
{
Console.WriteLine("Waiting for file to be released by process");
continue;
}
File.Move(e.FullPath, archivePath);
File.SetLastWriteTimeUtc(archivePath, DateTime.UtcNow);
}
catch (Exception err)
{
//log error
}
fileSystemWatcher1.EnableRaisingEvents = true;
string msg = string.Format("File {0} | {1}",
e.FullPath, e.ChangeType);
}
catch(Exception err)
{
//logs error
}
}
【问题讨论】:
-
你最好也订阅 Error 事件,这段代码可能不会导致问题。
-
程序崩溃了吗?
-
在您的第一个
try之前添加一个日志条目,只是为了确保它没有检测到更改。如果它每次都写入日志,那么至少您已经消除了未引发的 filewatcher 更改事件,并且实际上可以对您的代码进行故障排除 - 顺便说一下,乍一看似乎很好。 -
我将日志记录添加为 OnChanged 事件的第一行。对于我的测试,我将一个文件放入监视路径,等待它处理,然后将下一个文件放入(原始文件的克隆)。它处理了前 4 个文件,但甚至没有触发第 5 个文件的日志记录。我试图将 fileSystemWatcher 的 InternalBufferSize 增加到它的最大值(64kb),但我仍然看到同样的问题。
标签: c# .net io filesystemwatcher