c# FileSystemWatcher Created 事件不会为创建的所有文件触发

Gha*_*eak 5 c# file-watcher

我想将目录中创建的所有文件的文件信息插入数据库。如果我在目录中删除少量文件,我的程序将执行此操作,但如果我一次在目录中删除大量文件,则它不会获取所有文件(我没有进行大量测试,但它只插入了大约当我尝试一次将 800 个文件放入目录时,我的数据库中包含了 200 个名称)。

这是我的代码:

static void Main(string[] args)
{
    // Create a new FileSystemWatcher and set its properties.
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"C:\dropDirectory";

    // Add event handlers.
    watcher.Created += new FileSystemEventHandler(OnChanged);

    // Begin watching.
    watcher.EnableRaisingEvents = true;

    while(DateTime.Now.Hour < 10);
}

private static void OnChanged(object source, FileSystemEventArgs e)
{
    string strInsert = "INSERT INTO  Files (Filename) VALUES ('" + e.Name + "')";
    string strConnection = "Server = server_name; Database = database_name; User Id = user_id; Password = password;";
    using (SqlConnection con = new SqlConnection(strConnection))
    {
        using (SqlCommand cmd = new SqlCommand(strInsert, con))
        {   
            con.Open();
            cmd.ExecuteScalar();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要进行哪些更改,以便为目标目录中删除的每个文件调用我的 OnChanged 方法,无论一次删除的文件数量如何?提前致谢。

AAA*_*ddd 7

您的问题是缓冲区大小及其众所周知且有记录的问题

FileSystemWatcher使用带有一些相关标志的WinApi调用ReadDirectoryChangesW

当您第一次调用 时ReadDirectoryChangesW,系统会分配一个缓冲区来存储更改信息。该缓冲区与目录句柄相关联,直到它被关闭,并且其大小在其生命周期内不会改变。调用此函数之间发生的目录更改将添加到缓冲区中,然后在下一次调用时返回。如果缓冲区溢出,则丢弃缓冲区的全部内容

中的类似物FileSystemWatcherFileSystemWatcher.InternalBufferSize属性

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

系统通知组件文件更改,并将这些更改存储在组件创建的缓冲区中并传递给 API。每个事件最多可以使用 16 个字节的内存,不包括文件名。 如果短时间内发生多次变化,缓冲区可能会溢出。这会导致组件失去对目录中更改的跟踪,并且它只会提供全面通知。增加缓冲区的大小可以防止丢失文件系统更改事件。但是,增加缓冲区大小的成本很高,因为它来自无法换出到磁盘的非分页内存,因此请使缓冲区尽可能小。为了避免缓冲区溢出,请使用 NotifyFilter 和 IncludeSubdirectories 属性来过滤掉不需要的更改通知

如果情况变得更糟,您可以结合使用轮询和跟踪,它已经帮助我摆脱了几次麻烦。

  • 感谢您的回答,正是我所需要的。接受作为答案并尝试投票,但我的声誉太低而无法显示。再次感谢。 (3认同)