FileSystemWatcher无法正常工作

时间:2011-09-09 06:36:10

标签: c# filesystemwatcher asynchronous

我正在使用FileSystemWatcher扫描从Web应用程序上载文件的文件夹。我有超过1000个文件上传到该文件夹​​。现在,问题是FileSystemWatcher在复制第一个文件时启动,有时,它不适用于所有文件。任何建议都会非常值得赞赏。

2 个答案:

答案 0 :(得分:8)

FileSystemWatcher documentation说(强调我的):

  

Windows操作系统会通知组件文件更改   在FileSystemWatcher创建的缓冲区中。 如果有很多   在短时间内发生变化,缓冲区可能会溢出。这导致了   组件忘记跟踪目录中的更改,它只会   提供全面通知。增加缓冲区的大小   InternalBufferSize属性很昂贵,因为它来自   非分页内存,无法换出磁盘,所以保持   缓冲区虽小但足够大,不会错过任何文件更改事件。   要避免缓冲区溢出,请使用NotifyFilter和   IncludeSubdirectories属性,以便您可以过滤掉不需要的更改   通知。

  

请注意,FileSystemWatcher可能会在缓冲区大小时错过事件   超过了。为避免遗漏事件,请遵循以下准则:

     

通过设置InternalBufferSize属性来增加缓冲区大小。

     

避免使用长文件名观看文件,因为文件名较长   有助于填补缓冲区。考虑重命名这些文件   使用较短的名字。

     

尽可能缩短您的事件处理代码。

如果您已经尝试了上述内容并且它仍然不够可靠,我恐怕唯一的解决方案是订阅Error事件并在发生时手动枚举目录内容。

答案 1 :(得分:3)

详细说明Jon的答案:

还有另一种可能的解决方案可以延迟发生缓冲区溢出。例如,通过处理您监视的事件,Created事件,尽可能快地从缓冲区中删除与事件关联的信息,以便它可以回收此空间。

为了加快速度,您可以选择异步处理文件。触发事件后,您将队列的完整路径排入队列中的文件,而队列又将由工作线程处理。绑定到Created事件的事件处理程序的任务减少为向队列添加字符串(文件路径)。

例如:

public class FileProcessor
{
    private readonly Queue<string> files = new Queue<string>();

    public void EnqueueFile(string path)
    {
        files.Enqueue(path);
    }
}

附加到创建的事件的事件处理程序的代码可以最小化到:

static void file_Created(object sender, FileSystemEventArgs e)
{
    _fileProcessor.EnqueueFile(e.FullPath);
}

您可以在我两年前撰写的文章中找到有关此内容的更多信息(包括示例代码):

http://cgeers.com/2009/08/14/monitoring-a-directory/