too many changes at once in directory
我必须检测网络共享上的所有更改.
InternalBufferSize增加到8192 * 128
>将InternalBufferSize设置为支持的最大值(65536).您将其设置为“8192 * 128”的尝试大于documentation中列出的最大支持值,因此您可能根本没有增加缓冲区大小.
>将fileSystemWatcher中的事件排队到后台线程进行处理.
这是第二点,不太了解,真的应该在MSDN上记录.在内部,fileSystemWatcher将更改事件排队到您设置上面大小的内部缓冲区.但重要的是,只有在事件处理程序返回后才会从该缓冲区中删除项目.这意味着事件处理程序引入的每个开销周期都会增加缓冲区填满的可能性.您应该做的是尽快清除fileSystemWatcher的有限队列,并将事件移动到您自己的无限队列中,以您可以处理的速率处理,或者如果您愿意,可以丢弃,但是有一些智能它.
这基本上就是我在代码中所做的.首先,我开始自己的调度程序线程:
dispatcher changedispatcher = null;ManualresetEvent changedispatcherStarted = new ManualresetEvent(false);Action changeThreadHandler = () =>{ changedispatcher = dispatcher.Currentdispatcher; changedispatcherStarted.Set(); dispatcher.Run();};new Thread(() => changeThreadHandler()) { IsBackground = true }.Start();changedispatcherStarted.WaitOne();
然后我创建了观察者.请注意设置的缓冲区大小.就我而言,我只关注目标目录中的更改,而不是子目录:
fileSystemWatcher watcher = new fileSystemWatcher();watcher.Path = path;watcher.InternalBufferSize = 64 * 1024;watcher.IncludeSubdirectorIEs = false;
现在我附加了我的事件处理程序,但是在这里我将它们调用到我的调度程序而不是在观察程序线程中同步运行它们.是的,调度员将按顺序处理事件:
watcher.Changed += (sender,e) => changedispatcher.BeginInvoke(new Action(() => OnChanged(sender,e)));watcher.Created += (sender,e) => changedispatcher.BeginInvoke(new Action(() => OnCreated(sender,e)));watcher.Deleted += (sender,e) => changedispatcher.BeginInvoke(new Action(() => OnDeleted(sender,e)));watcher.Renamed += (sender,e) => changedispatcher.BeginInvoke(new Action(() => OnRenamed(sender,e)));
最后,在处理完fileSystemWatcher之后(你正在这样做,对吧?),你需要关闭你的调度员:
watcher.dispose()changedispatcher.BeginInvokeShutdown(dispatcherPriority.normal);
就是这样.在网络和本地场景中,我自己都遇到了这个问题.使用这种方法后,我无法再次生成此错误,即使在尽可能快地将空文件敲打到监视目录时也是如此.如果你曾经设法以某种方式耗尽这种情况下的缓冲区(我不确定是否可能,API上游可能更慢),这里还有进一步优化的空间.只要您的调度程序超过了“临界点”,发送方无法以比发送方式更快的速度发布事件,您将永远不会得到积压,因此永远不会破坏缓冲区.我相信这种方法可以让你进入安全区域.
总结以上是内存溢出为你收集整理的c# – 避免在目录中一次更改错误太多全部内容,希望文章能够帮你解决c# – 避免在目录中一次更改错误太多所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)