【问题标题】:c# FileSystemWatcher stops firing events after sometimec# FileSystemWatcher 在一段时间后停止触发事件
【发布时间】:2018-09-26 20:26:26
【问题描述】:

我想跟踪特定路径的文件更改,我已经完成了现在工作正常的代码。它正在跟踪文件创建、重命名和更改。

我的问题是当我启动 Filesystemwatcher 时它工作正常,但一段时间后它停止工作,即它停止触发创建、删除和更改事件。

谁能帮帮我?

提前谢谢你。

这是我的代码 lstFolder 是我的多路径列表

this.listFileSystemWatcher = new List();

            // Loop the list to process each of the folder specifications found
            if (lstFolder.Count > 0)// check if path is available to watch else exit file watcher
            {
                foreach (CustomFolderSettings customFolder in lstFolder)
                {
                    DirectoryInfo dir = new DirectoryInfo(customFolder.FWPath);
                    // Checks whether the folder is enabled and
                    // also the directory is a valid location
                    if (dir.Exists)//customFolder.FolderEnabled && 
                    {
                        customFolder.AllowedFiles = customFolder.FWExtension;// setting extension to allowed filw extension to log .
                        foreach (var strExt in customFolder.FWExtension.Split(','))
                        {

                            // Creates a new instance of FileSystemWatcher
                            //FileSystemWatcher fileSWatch = new FileSystemWatcher();
                             this.fileSWatch = new FileSystemWatcher();
                            // Sets the filter
                            fileSWatch.Filter = strExt;// customFolder.FolderFilter;
                                                       // Sets the folder location
                            fileSWatch.Path = customFolder.FWPath;
                            fileSWatch.InternalBufferSize = 64000;
                            // Sets the action to be executed
                            StringBuilder actionToExecute = new StringBuilder(customFolder.ExecutableFile);
                            // List of arguments
                            StringBuilder actionArguments = new StringBuilder(customFolder.ExecutableArguments);
                            // Subscribe to notify filters
                            fileSWatch.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                            // Associate the events that will be triggered when a new file Created,Changed,Deleted,Renamed //
                            // is added to the monitored folder, using a lambda expression                   
                            fileSWatch.Created += (senderObj, fileSysArgs) => fileSWatch_Created(senderObj, fileSysArgs, actionToExecute.ToString(), customFolder.AllowedFiles);
                            fileSWatch.Changed += (senderObj, fileSysArgs) => fileSWatch_Changed(senderObj, fileSysArgs, actionToExecute.ToString(), customFolder.AllowedFiles);

                            fileSWatch.Deleted += (senderObj, fileSysArgs) => fileSWatch_Deleted(senderObj, fileSysArgs, actionToExecute.ToString(), customFolder.AllowedFiles);
                            fileSWatch.Renamed += (senderObj, fileSysArgs) => fileSWatch_Renamed(senderObj, fileSysArgs, actionToExecute.ToString(), customFolder.AllowedFiles);
                            fileSWatch.Error += (senderObj, fileSysArgs) => fileSWatch_Error(senderObj, fileSysArgs, actionToExecute.ToString(), customFolder.AllowedFiles);


                            // will track changes in sub-folders as well
                            fileSWatch.IncludeSubdirectories = customFolder.FWSubFolders;
                            // Begin watching
                            fileSWatch.EnableRaisingEvents = true;


                            // Add the systemWatcher to the list
                            listFileSystemWatcher.Add(fileSWatch);
                            GC.KeepAlive(fileSWatch);
                            GC.KeepAlive(listFileSystemWatcher);
                        }

                    }
                }

            }
            else
            {
                Application.Exit();
            }

【问题讨论】:

  • 它是完全停止工作还是丢弃事件?
  • 我无法理解。经过一段时间的空闲时间后,它无法跟踪文件更改。
  • 我想我在几年前读过一些类似的东西。问题被设置为一个非常大的缓冲区。我看到你使用fileSWatch.InternalBufferSize。尝试更改该值,或将其删除。我不知道很久以前的问题是什么,但我认为速度很慢,因为缓冲区大(不幸的是我不记得它是否也有停止事件的问题)
  • (萨鲁曼回应后) 当你的文件改动太多,无法使用指定过滤时,尝试返工函数fileSWatch_*只收集事件(例如到List并在较低优先级的线程中处理信息。这至少应该允许您以更快的速度清除缓冲区。但请记住,长缓冲区意味着处理速度较慢(在系统中)

标签: c#


【解决方案1】:

不要使用

GC.KeepAlive(fileSWatch);
GC.KeepAlive(listFileSystemWatcher);

创建一个List<FileSystemWatcher> 并改为存储每一个

也可以看看

Events and Buffer Sizes

请注意,有几个因素会影响哪些文件系统更改事件 引发,如下所述:

  • 常见的文件系统操作可能会引发多个事件。例如,当一个文件从一个目录移动到另一个目录时,几个 可能会引发 OnChanged 和一些 OnCreated 和 OnDeleted 事件。 移动文件是一项复杂的操作,由多个简单的 操作,因此引发多个事件。同样,一些 应用程序(例如,防病毒软件)可能会导致额外的 FileSystemWatcher 检测到的文件系统事件。
  • FileSystemWatcher 可以监视磁盘,只要它们没有被切换或删除。 FileSystemWatcher 不会引发事件 CD 和 DVD,因为时间戳和属性无法更改。偏僻的 计算机必须安装了所需的平台之一 组件才能正常工作。
  • 如果多个 FileSystemWatcher 对象在 Service Pack 1 之前的 Windows XP 或 Windows 2000 SP2 或更早版本中监视相同的 UNC 路径, 那么只有其中一个对象会引发事件。在运行的机器上 Windows XP SP1 及更新版本、Windows 2000 SP3 或更新版本或 Windows Server 2003 年,所有 FileSystemWatcher 对象都会引发相应的事件。

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

  • 通过设置 InternalBufferSize 属性增加缓冲区大小。
  • 避免使用长文件名查看文件,因为长文件名会导致缓冲区被填满。考虑重命名这些文件 使用较短的名称。
  • 尽可能缩短事件处理代码。

FileSystemWatcher.InternalBufferSize Property

备注

您可以将缓冲区设置为 4 KB 或更大,但不得超过 64 知识库。如果您尝试将 InternalBufferSize 属性设置为小于 4096 字节,您的值被丢弃并且 InternalBufferSize 属性设置为 4096 字节。为获得最佳性能,请使用 在基于 Intel 的计算机上为 4 KB。

系统将文件更改通知组件,并将这些更改存储在 组件创建并传递给 API 的缓冲区中的更改。每个 event 最多可以使用 16 字节的内存,不包括文件名。 如果短时间内有很多变化,缓冲区可能会溢出。 这会导致组件失去对目录更改的跟踪, 它只会提供一揽子通知。

增加缓冲区的大小可以防止丢失文件系统 改变事件。然而,增加缓冲区大小是昂贵的,因为 它来自无法换出到磁盘的非分页内存,所以 保持缓冲区尽可能小。为避免缓冲区溢出,请使用 要过滤掉的 NotifyFilter 和 IncludeSubdirectories 属性 不需要的更改通知。

【讨论】:

  • 感谢您的回复
  • 我试过删除 fileSWatch.InternalBufferSize = 64000;但问题仍然存在。关于 GC 我在某处读到 GC 强行销毁文件观察程序对象,这可能是一个原因,所以我这样做了,但问题没有得到解决。