在特定线程上让观察者正常工作时遇到问题。
Subject<bool> subjEvent = new Subject<bool>();
Subject<int> subjValue = new Subject<int>();
IScheduler sched = new EventLoopScheduler(ts => new Thread(ts));
subjEvent.ObserveOn(sched).Subscribe(
r =>
{
if(r)
{
Console.WriteLine("Connected On: \t{0}", Thread.CurrentThread.ManagedThreadId);
subjValue.ObserveOn(sched).Subscribe(
x => Console.WriteLine("Recieved On: \t{0}", Thread.CurrentThread.ManagedThreadId));
}else{
Console.WriteLine("Disconnect On: \t{0}", Thread.CurrentThread.ManagedThreadId);
}
}
);
subjEvent.OnNext(true);
for(int i=0; i< 10; i++)
{
subjValue.OnNext(i);
}
subjEvent.OnNext(false);
subjValue.OnCompleted();
subjEvent.OnCompleted();
这个想法是在可用时订阅某些内容,然后取消订阅/重新订阅事件。现在我需要观察一个特定的(读取相同的)线程,以及确保正确的排序,我有一个EventLoopScheduler。
问题是我从价值订阅中得不到任何东西。
现在,如果我将Thread.Sleep(10)添加到生成循环(OnNext之后),它可以正常工作。所以我对我做错了什么感到困惑,并且非常感谢帮助/建议。
答案 0 :(得分:3)
虽然这无助于直接回答你的问题 - 我认为Asti做得很好 - 我想我会发布这段代码来帮助你写出你的问题。
你应该非常努力不要订阅你的观察者,直到你必须这样做。当您执行OnNext
处理程序中的代码时,需要尽可能小。
尝试此版本的查询:
var query =
from b in subjEvent.Do(x =>
Console.WriteLine("{0}onnected On: \t{1}",
x ? "C" : "Disc",
Thread.CurrentThread.ManagedThreadId))
select b ? subjValue : Observable.Empty<int>();
query.Switch().Subscribe(x =>
Console.WriteLine("Recieved On: \t{0}",
Thread.CurrentThread.ManagedThreadId));
除了事件循环调度程序的问题,此代码与您的代码相同,但它只有一个订阅,并且它在该订阅中执行的工作量最小。我希望这会有所帮助。
答案 1 :(得分:2)
这虽然是非确定性的预期行为。
问题是第二个订阅是在EventLoopScheduler
中设置的。设置订阅以供调度程序观察需要一些时间。但是它的通知已经在主线程中进行了。在设置订阅时,循环将完成执行。
要查看此情况,请从活动主题中移除ObserveOn
。这将强制在继续使用值通知第二个主题之前设置订阅。您还可以在OnNext(true)
之后留出一些时间来允许它连接订阅。