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.