我设置了FileSystemWatcher来检查新文件,将内容存储在数据库中并删除文件。大约10天前,它开始忽略一些文件。我们讨论的是总共50,000个文件中的1,500个文件。通过手动将文件移动到另一个目录,然后再将它们移动到监视目录,文件就会被注意到。
InternalBufferSize设置为32 kB以处理大批量。它一次处理300多个文件而没有任何问题,而现实甚至不是那么接近。
该程序最后一次涉及40天前,因为与FileSystemWatcher无关的更改。它已经生产了一年多了。服务器负载中没有出现峰值。
什么可能导致这样的问题突然出现? FileSystemWatcher是否有可能只是unreliable?
修改 我创建了一个测试,创建了1,000个文件。运行后,可以在事件日志中找到3,000个条目。所以我认为缓冲区溢出是不可能的?
private void button1_Click(object sender, EventArgs e)
{
fsw = new FileSystemWatcher();
fsw.Path = @"C:\temp\fsw-test";
fsw.IncludeSubdirectories = false;
fsw.NotifyFilter = NotifyFilters.FileName;
fsw.Created += new FileSystemEventHandler(fsw_Created_handler);
fsw.EnableRaisingEvents = true;
fsw.InternalBufferSize = 32768;
fsw.Error += fsw_Error_handler;
}
private void fsw_Created_handler(object sender, FileSystemEventArgs e)
{
new Thread(new ParameterizedThreadStart(work)).Start(e);
}
private void fsw_Error_handler(object sender, ErrorEventArgs e)
{
EventLog.WriteEntry("few test", e.GetException().Message);
}
private void work(object e)
{
try
{
EventLog.WriteEntry("fsw test", "Queueing File Started");
Thread.Sleep(10000);
EventLog.WriteEntry("fsw test", ((FileSystemEventArgs)e).Name);
EventLog.WriteEntry("fsw test", "Queueing File Done");
}
catch (Exception ex)
{
EventLog.WriteEntry("fsw test", "Error = " + ex.StackTrace + " *** " + ex.ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 1000; i++)
{
System.IO.File.Create(@"C:\temp\fsw-test\" + i);
}
}
编辑2 以多种方式对程序进行压力测试并反复检查代码,这表明没有任何问题。所以现在它是一个不可复制的错误,我会做一些更改,让它更频繁地记录并监控情况。
答案 0 :(得分:3)
文件事件未排队。如果您正在处理文件,并且创建了新文件,那么您将错过这些事件。
解决此问题的一种方法是,当发生新文件事件时,处理该文件并在返回之前检查新文件。循环直到没有文件遗留下来。
答案 1 :(得分:0)
问题原因是由多线程引起的Queue
损坏。