当许多文件同时添加到目录时,FileSystemWatcher无法正常工作

当许多文件同时添加到目录时,FileSystemWatcher无法正常工作……

Watcher根本找不到目录中的所有文件 – 只有当文件一个接一个地放在文件夹中时 – 而不是同时将大量文件复制到文件夹中…

Threads的创建是问题的解决方案还是有另一种方法来处理问题?

该类的文档详细说明了该问题:

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

所以,在这种情况下,线程可能对你没什么帮助。 您可能希望增加缓冲区大小(但它应该多大可能取决于计算机和磁盘本身的速度)或通过设置适当的filter来约束您感兴趣的文件。

C#对我来说是新的,我在同样的麻烦中挣扎了近一个星期。 我有这个:

private void btnWatchFile_Click(object sender, EventArgs e) { //code to create a watcher and allow it to reise events... } //watcher onCreate event public void onCreated(object sender, FileSystemEventArgs e) { if (!updateNotifications ) { stringBuilder.Remove(0, stringBuilder.Length); stringBuilder.Append(e.FullPath); stringBuilder.Append(" "); stringBuilder.Append(e.ChangeType.ToString()); stringBuilder.Append(" "); stringBuilder.Append(DateTime.Now.ToString()); updateNotifications = true; } } //timer to check the flag every X time private void timer_Tick(object sender, EventArgs e) { if (updateNotifications ) { notificationListBox.Items.Insert(0, stringBuilder.ToString()); updateNotifications = false; } } 

我甚至将计时器间隔设置为1毫秒,但是缺少一些新的文件事件。 我试图从onCreated事件中更新notificationsListBox ,但我总是遇到交叉引用错误。 这是直到我发现观察者onCreated事件是在一个主方法线程之外的线程中执行的,因此,在一个坚果shell中,这是我的解决方案:

我将public delegate void Action()作为我的类的属性包含在内,然后使用InvokeonCreated事件中更新notificationsListBox 。 接下来,件代码:

  public void onCreated(object sender, FileSystemEventArgs e) { stringBuilder.Remove(0, stringBuilder.Length); stringBuilder.Append(e.FullPath); stringBuilder.Append(" "); stringBuilder.Append(e.ChangeType.ToString()); stringBuilder.Append(" "); stringBuilder.Append(DateTime.Now.ToString()); updateNotifications = true; Invoke((Action)(() => {notificationListBox.Items.Insert(0, stringBuilder.ToString());})); } 

因此不再需要计时器及其代码。 这对我来说非常好,我希望它适用于任何有类似情况的人。 最好的祝福!!!

尝试这样的事情。

 public MainWindow() { InitializeComponent(); #region initialise FileSystemWatcher FileSystemWatcher watch = new FileSystemWatcher(); watch.Path = folder; watch.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName; watch.Filter = ext; watch.Changed += new FileSystemEventHandler(OnChanged); watch.Created += new FileSystemEventHandler(OnChanged); watch.EnableRaisingEvents = true; #endregion } private void OnChanged(object source, FileSystemEventArgs e) { Application.Current.Dispatcher.BeginInvoke((Action)delegate { // do your work here. If this work needs more time than it can be processed, not the filesystembuffer overflows but your application will block. In this case try to improve performance here. }, System.Windows.Threading.DispatcherPriority.Normal); }