简体   繁体   中英

Rx .net Subscribe() and EventPattern oddity

I'm using Rx in conjunction with a third-party API that uses the EventPattern . In this API you register your event handlers on the object and then invoke a method, StartWatching() , on the object that starts the events to begin triggering. I am using Observable.FromEventPattern to bridge the API in the Rx world but I am running into very odd problems where subscriptions will only work if they are called right by the invocation of StartWatching() . Below is a reduced case of what I am seeing.

This works:

foreach (var iq in interactionQueues)
        {
            Observable.FromEventPattern(iq, "TheEvent")
                .Subscribe(e => Log.Info("I got called!"), 
                       e => Log.Info("Error!", e),
                       () => Console.WriteLine("Seq completed!"));

            iq.StartWatching();
        }

If I call the Subscribe() and StartWatching() in different loops it stops working:

foreach (var iq in interactionQueues)
            Observable.FromEventPattern(iq, "TheEvent")
                .Subscribe(e => Log.Info("I got called!"), 
                       e => Log.Info("Error!", e),
                       () => Console.WriteLine("Seq completed!"));
foreach (var iq in interactionQueues)
           iq.StartWatching();

My only thought as to why this may happen is that the Observing or Subscribing is happening on the wrong thread. I have tried using Scheduler.CurrentThread and Scheduler.Immediate with SubscribeOn and ObserveOn but that didn't help. Any other ideas? Should I try a different Scheduler or is that a red herring?

Let's wrap this in a more friendly method:

public static TheEventArgs WatchEvent(this InteractionQueue this)
{
    var ret = Observable.Create<TheEventArgs>(subj => {
        // This entire block gets called every time someone calls Subscribe
        var disp = new CompositeDisposable();

        // Subscribe to the event
        disp.Add(Observable.FromEventPattern(iq, "TheEvent").Subscribe(subj));

        // Stop watching when we're done
        disp.Add(Disposable.Create(() => iq.StopWatching());

        iq.StartWatching();

        // This is what to Dispose on Unsubscribe
        return disp;
    });

    // When > 1 person Subscribes, only call the block above (i.e. StartWatching) once
    return ret.Multicast(new Subject<TheEventArgs>()).RefCount();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM