2012-02-13 56 views
2

我有一个FileSystemWatcher设置为检查新文件,将内容存储在数据库中并删除文件。大约10天前,它开始忽略一些文件。我们正在讨论总共50,000个文件中的1500个文件。通过手动将文件移动到不同的目录,然后再将它们移动到观看的目录,这些文件就会被注意到。FileSystemWatcher有时不工作

InternalBufferSize设置为32 kB来处理大批量。它一次处理300多个文件,没有问题,现实甚至没有那么接近。

该程序最后一次触及的时间超过40天,因此无法与FileSystemWatcher进行更改。它已经生产了一年多了。在服务器负载中不会出现尖峰。

什么会导致像这样的问题突然出现?有没有可能FileSystemWatcher只是unreliable

编辑 我创建了一个测试,其中创建了1,000个文件。运行后,可以在事件日志中找到3000个条目。所以我认为缓冲区溢出是不可能的?

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

我可以给出的唯一建议是'FileSystemWatcher'的一些选项相当隐晦。当我使用它时,我设置了我认为能够读取/写入/编辑的内容,但没有抓住所有这些内容。也许一些新的“案例”如何“创造”文件已经出现,并且FSW没有被设置为捕捉它们,但它仍然被设置为捕捉“移动”,这就是为什么将它们从一个目录移动到另一个目录作品。 – Origin 2012-02-13 15:46:43

+0

@Origin每个文件都以完全相同的方式进入系统。 – Stijn 2012-02-13 15:50:07

+0

你在监视来自观察者的'Error'事件吗? – adrianm 2012-02-13 15:50:44

回答

0

问题原来是由多线程造成的Queue损坏。

2

文件事件没有排队。如果您正在处理文件,并且创建了新文件,您将错过这些事件。

解决此问题的一种方法是,当发生新文件事件时,在文件上工作并在返回之前检查新文件。循环直到没有文件离开。

+0

如果这是真的,那么就有可能无法解决的内在竞争(即使它很小) - 在事件处理程序确定没有新文件之后,当文件系统更改可能发生时总会有一段短的时间在控制返回到任何启动事件之前。 – 2012-02-13 15:51:13

+0

“创建”事件的处理程序每​​次都会启动一个新线程来执行实际处理。如问题所述,我可以在目录中放置300多个文件,并且每个文件都将被处理。或者我误解你的意思?解决方法确实是一种可能性,但是我还可以完全放弃FileSystemWatcher并定期轮询文件目录。 – Stijn 2012-02-13 15:57:31

+0

您可以轻松验证它。在事件处理程序中,放入10秒钟的睡眠。在该代码处于睡眠状态时,创建一个新文件并查看是否有其他事件。我提出了一个解决方案,对我们有效,我确信还有其他解决方案。 – 2012-02-13 16:03:40