首页 > 解决方案 > c# FileSystemWatcher 在一段时间后停止触发事件

问题描述

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

我的问题是当我启动 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();
            }

标签: c#

解决方案


不要使用

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

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

也看看

事件和缓冲区大小

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

  • 常见的文件系统操作可能会引发多个事件。例如,当一个文件从一个目录移动到另一个目录时,可能会引发几个 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 属性

评论

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

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

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


推荐阅读