我正在使用FileSystemWatcher扫描从Web应用程序上载文件的文件夹。我有超过1000个文件上传到该文件夹。现在,问题是FileSystemWatcher在复制第一个文件时启动,有时,它不适用于所有文件。任何建议都会非常值得赞赏。
答案 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);
}
您可以在我两年前撰写的文章中找到有关此内容的更多信息(包括示例代码):