gpt4 book ai didi

.net - 响应式(Reactive)扩展与 FileSystemWatcher

转载 作者:行者123 更新时间:2023-12-03 13:32:03 25 4
gpt4 key购买 nike

FileSystemWatcher 长期以来一直困扰着我的一件事是它为文件的单个逻辑更改触发多个事件的方式。我知道它为什么会发生,但我不想关心 - 我只想重新解析文件一次,而不是连续 4-6 次。理想情况下,只有在给定文件完成更改时才会触发一个事件,而不是沿途的每一步。

多年来,我为这个问题提出了各种不同程度的丑陋解决方案。我认为 Reactive Extensions 将是最终的解决方案,但有些事情我做得不对,我希望有人能指出我的错误。

我有一个扩展方法:

public static IObservable<IEvent<FileSystemEventArgs>> GetChanged(this FileSystemWatcher that)
{
return Observable.FromEvent<FileSystemEventArgs>(that, "Changed");
}

最终,我想在给定的时间段内为每个文件名获取一个事件 - 这样,连续四个具有单个文件名的事件减少为一个事件,但如果同时修改多个文件,我不会丢失任何内容时间。 BufferWithTime听起来像是理想的解决方案。
var bufferedChange = watcher.GetChanged()
.Select(e => e.EventArgs.FullPath)
.BufferWithTime(TimeSpan.FromSeconds(1))
.Where(e => e.Count > 0)
.Select(e => e.Distinct());

当我订阅这个 observable 时,对受监视文件的一次更改会连续四次触发我的订阅方法,这与目的相反。如果我删除 Distinct()调用,我看到四个调用中的每一个都包含两个相同的事件-因此正在进行一些缓冲。增加传递给 BufferWithTime 的时间跨度似乎没有任何效果 - 我高达 20 秒,但行为没有任何变化。

这是我第一次涉足 Rx,所以我可能遗漏了一些明显的东西。我做错了吗?有更好的方法吗?感谢您的任何建议...

最佳答案

只是为了热身一个老话题,因为我现在也在做这个:

当然,在观看一个文件的情况下,这个主题可以忽略不计,因为当您通过

_fileSystemWatcher.NotifyFilter = NotifyFilters.Size | ....

但是让我们假设 FileSystemWatcher 会连续触发许多事件(可能许多文件被更改/重命名/创建),其他人读到这个:

在这种情况下,您不想使用 Throttle 或 BufferWithTime: Throttle有点误导..它禁止任何触发,直到 TimeSpan 时间过去而没有事件。含义:当您使用 Throttle(TimeSpan.FromMilliseconds(200)) 之类的内容时,它永远不会触发,并且在每个事件之后都有一个 < 200 ms 的暂停。所以这并不是人们所期望的“节流”。当您想等到用户停止输入某些内容时,这对用户输入很有用。这对负载节流不利。
BufferWithTime也不是您想要的:它只是填充时间缓冲区。当每个事件的初始负载很高时很好,例如打开到 Web 服务的连接。在这种情况下,您可能希望每隔“时间”秒批处理一次事件。但不是在负载平衡时,因为事件的数量不会改变。

解决方案是 Sample(TimeSpan time)方法:它采用 TimeSpan 内的最后一个事件,即“真正的”Throttle。我认为在这种情况下,Rx 的人真的搞砸了命名。

关于.net - 响应式(Reactive)扩展与 FileSystemWatcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2677976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com