winforms FileSystemWatcher在C# Windows窗体中抛出System.IO.InternalBufferOverflowException [已关闭]

jfewjypa  于 2023-03-31  发布在  C#
关注(0)|答案(1)|浏览(152)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
6天前关闭。
这篇文章是编辑和提交审查3天前。
Improve this question
我在C#中创建了一个应用程序,该应用程序不断侦听文件夹中的新文件添加,一旦添加了新文件,它就会拾取该文件并将其上传到S3存储桶。我用4-5个文件测试了应用程序,它工作得很好,但当我向该文件夹添加55个文件时,应用程序抛出“System.IO.InternalBufferOverflowException”错误。我该怎么做?

我在考虑增加FileSystemWatcher的缓冲区大小,但我不太确定这是否是正确的方法。
这是我在Home中编写的FileSystemWatcher的代码。我如何修改它以将info对象入队,以便稍后在不同的线程上处理?

private async void Home_Shown(Object sender, EventArgs e) {
    public FileSystemWatcher watcher = new FileSystemWatcher(envFolderLocation);
    watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
    
    watcher.Created += OnCreated;
    watcher.Changed += OnChanged;
    watcher.Error += OnError;
    
    watcher.EnableRaisingEvents = true;
}

我的目标是完全避免这种异常,即使快速添加了大量文件,也能处理文件夹中的文件。

lkaoscv7

lkaoscv71#

InternalBufferOverflowException的文档说明
FileSystemWatcher中,当您收到文件更改的通知时,系统将这些更改存储在组件创建的缓冲区中,并将其传递给应用程序编程接口(API)。如果在短时间内有许多更改,缓冲区很容易溢出,导致引发异常,这实质上会丢失所有更改。为了防止缓冲区溢出,使用FileSystemWatcher.NotifyFilterFileSystemWatcher.IncludeSubdirectories属性来过滤掉不需要的更改通知。您还可以通过FileSystemWatcher.InternalBufferSize属性来增加内部缓冲区的大小。但是,增加缓冲区的大小代价很高,因此请尽可能保持缓冲区较小。
因此,有几种补救措施,你可以尝试,而且,最有可能的是,你将需要应用其中的一些组合。
1.您应该尝试的第一个设置是使用NotifyFilterIncludeSubdirectories属性进行过滤。这些属性直接影响您需要查看的事件数量和范围,因此应该首先尝试这些属性。您可能更关心新文件是否完整*并创建(例如),而不是文件属性和安全性的更改。
1.因为事件处理是顺序的,并且仅限于内部缓冲区,并且因为您为每个事件所做的 * 是内联的,所以您可以卸载它。Fildor在您的帖子的评论中建议这样做。这是一个很好的第二道防线。我的建议是使用ConcurrentQueue和一个后台线程或任务来出队并处理事件。
1.最后,你可以增加缓冲区的大小,如文档中所述。你可以按照链接到InternalBufferSize的原因,他们说它是昂贵的。它更有可能再次导致问题,甚至更大的更改集。
FWIW,GitHub上有一个outstanding issue(自2015年以来!)来添加事件缓冲。这类似于上面的第2点。
* Complete是FSW不能顺便传达的东西。complete是什么意思?从观察者的Angular 来看,真正解决这个问题的唯一方法是使用启发式方法,例如最近一次修改发生在5秒前。但即使这样也充满了危险(谢谢
”(《论语》)。

相关问题