C# Subject.OnNext(值)一次向观察者发出多个通知(对于相同的更改值)
这种行为真的很奇怪,它看起来像框架本身的一个巨大缺陷 我有一个FileSystemWatcher来检测文件夹中的新文件,每次检测到新文件时,在发送Rx.OnNext通知之前,该文件都会被解析和删除:C# Subject.OnNext(值)一次向观察者发出多个通知(对于相同的更改值),c#,.net,visual-studio,system.reactive,reactive-programming,C#,.net,Visual Studio,System.reactive,Reactive Programming,这种行为真的很奇怪,它看起来像框架本身的一个巨大缺陷 我有一个FileSystemWatcher来检测文件夹中的新文件,每次检测到新文件时,在发送Rx.OnNext通知之前,该文件都会被解析和删除: private Subject<MyObject> objectNotification = new Subject<MyObject>(); private FileSystemWatcher watcher; private void MyClassConstructo
private Subject<MyObject> objectNotification = new Subject<MyObject>();
private FileSystemWatcher watcher;
private void MyClassConstructor(string pathToWatch)
{
watcher= new FileSystemWatcher();
watcher.Filter = scraper.Ext;
watcher.Created += new FileSystemEventHandler(parseMethod);
watcher.Path = pathToWatch;
watcher.EnableRaisingEvents = true;
}
private void parseMethod(object sender, FileSystemEventArgs e)
{
MyObject parsedFile = new MyObject(e.FullPath);
File.Delete(e.FullPath);
var syncedSubject = Subject.Synchronize(objectNotification);
syncedSubject.OnNext(parsedFile);
}
理想情况下,对于sender类发送的每个值,我都应该在observer中收到一个通知,不幸的是,我得到了更多,更多 可观测同步是这个问题的核心问题 Subject或Observable同步方法可防止对XXX进行并发调用 由于同步在不必要时(通常已经足够)引入开销,并且由于下面描述的替代方法,因此rxapi的用户需要决定何时以及如何进行同步 在您的情况下,每次引发事件并调用事件处理程序时,
parseMethod
都会为该事件创建一个新的同步主题。这不是您想要的,也不会阻止并发的OnNext()
调用。因此,由于observerOnNext()
处理程序中的并发调用,您看到了一个竞争条件错误
与其在parseMethod
中创建同步主题,不如在构造函数中创建同步主题,或者在订阅上同步主题,这样应该可以工作
e、 g:
要么这样做:
private ISubject<MyObject,MyObject> objectNotification =
Subject.Synchronized(new Subject<MyObject>());
...
private void parseMethod(object sender, FileSystemEventArgs e)
{
MyObject parsedFile = new MyObject(e.FullPath);
File.Delete(e.FullPath);
objectNotification.OnNext(parsedFile);
}
private void initSubscription()
{
this.myObjectSubscription = sendingClass.Synchronize().Subscribe(parsedObject =>
{
this.AddObject(parsedObject);
});
}
请注意,在多个订阅者的情况下,这些备选方案具有不同的行为
在第一种情况下,您要确保所有观察者中最多有一个OnNext()
。第一个事件转到第一个订阅者,然后转到第二个订阅者。。。在所有订户都收到该事件之前,将发送第二个事件,以此类推
在第二种情况下,您引入了一些(通常是安全的)并发性—现在您可以确保在所有观察者中,对于一个特定事件,最多有一个OnNext()
。换言之,可以在不同的观察者中对不同的事件进行并发调用,但在任何时候都只有一个给定事件的调用处于运行状态,并且不会对同一观察者进行并发调用
你喜欢哪一个取决于你,后者允许观察者并行运行,但仍然会阻止你看到的问题;哪种方法更好取决于上面未提供的实现细节。您确定不是FileSystemWatcher多次通知您吗?这“理论上”不可能,因为我们讨论的是约200字节的文件。。。但是,如果你让我觉得在通过WiFi连接的Samba网络共享中观看文件时会出现问题,那么可能是FileSystemWatcher的行为就像观看需要在多个字节块中读取/写入的大文件,并在每个字节块中引发一个事件?可能是吗?(无论如何很难复制)请参阅添加的一些详细信息,解释
同步
备选方案的行为变化。
private void initSubscription()
{
this.myObjectSubscription = sendingClass.Synchronize().Subscribe(parsedObject =>
{
this.AddObject(parsedObject);
});
}