C# Rx.net Subscribe()和EventPattern oddity

C# Rx.net Subscribe()和EventPattern oddity,c#,.net,system.reactive,C#,.net,System.reactive,我将Rx与使用EventPattern的第三方API结合使用。在此API中,您在对象上注册事件处理程序,然后在启动事件以开始触发的对象上调用方法StartWatching()。我正在使用Observable.FromEventPattern在Rx世界架起API的桥梁,但我遇到了非常奇怪的问题,只有通过调用StartWatching()正确调用订阅,订阅才会起作用。下面是我所看到的一个简化案例 这项工作: foreach (var iq in interactionQueues)

我将Rx与使用
EventPattern
的第三方API结合使用。在此API中,您在对象上注册事件处理程序,然后在启动事件以开始触发的对象上调用方法
StartWatching()
。我正在使用
Observable.FromEventPattern
在Rx世界架起API的桥梁,但我遇到了非常奇怪的问题,只有通过调用
StartWatching()
正确调用订阅,订阅才会起作用。下面是我所看到的一个简化案例

这项工作:

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();
        }
如果我在不同的循环中调用
Subscribe()
startWatch()
,它将停止工作:

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();

我唯一想知道为什么会发生这种情况的是,观察或订阅发生在错误的线程上。我曾尝试使用
Scheduler.CurrentThread
Scheduler.Immediate
SubscribeOn
ObserveOn
一起使用,但没有任何帮助。还有其他想法吗?我应该尝试另一种
调度程序吗
,还是说这是一种误导?

让我们用一种更友好的方法来总结一下:

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();
}
public static TheEventArgs WatchEvent(此交互队列此)
{
var ret=可观察的。创建(sub=>{
//每次有人调用Subscribe时,都会调用整个块
var disp=新的CompositeDisposable();
//订阅活动
显示添加(从事件模式(iq,“TheEvent”).Subscribe(subc))可观察到);
//我们做完后别再看了
disp.Add(Disposable.Create(()=>iq.StopWatching());
iq.开始匹配();
//这是取消订阅时要处理的内容
返回disp;
});
//当>1人订阅时,只调用上面的块(即StartWatching)一次
返回ret.Multicast(新主题()).RefCount();
}

可能是interactionQueues.Next()在每次调用时都会生成新对象?如果您在错误的对象上调用
StartWatching
。Doh,您是对的@Lazin!在我的集合上调用
ToArray()
以强制实现修复了问题。这使得奇怪的订阅问题更有意义。:)耶,奥卡姆剃须刀。:)如果你想让你的评论成为一个答案,我会接受的。不管是什么情况,分离订阅(Observable.Subscribe)和订阅初始化(startwatch)都不是一个好主意。您需要创建单个
cold
observable,它将在内部调用
StartWatching
和ref count订户。我认为Paul的解决方案将很好地解决这个问题。非常好,我计划更好地完成资源管理,这看起来是一个很好的解决方案。谢谢我唯一不明白的是如何使用
多播(…)
而不仅仅是
Publish().RefCount()
Publish()
不会做同样的事情吗?还是您只是想避免调用
Connect()
?您完全正确,
Publish().RefCount()也是一样,我只是习惯于总是使用多播