C# Subject.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

这种行为真的很奇怪,它看起来像框架本身的一个巨大缺陷

我有一个FileSystemWatcher来检测文件夹中的新文件,每次检测到新文件时,在发送Rx.OnNext通知之前,该文件都会被解析和删除:

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()
调用。因此,由于observer
OnNext()
处理程序中的并发调用,您看到了一个竞争条件错误

与其在
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);
    });
}