[英]Nested Subscriptions in Reactive Extentions
我在使特定線程上的觀察者正常工作時遇到問題。
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之后),則可以正常工作。 因此,我對自己做錯了事感到困惑,非常感謝您的幫助/咨詢。
雖然這並不能直接幫助您回答問題-我認為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));
除非事件循環調度程序有問題,此代碼與您的代碼相同,但它只有一個訂閱,並且在該訂閱中所做的工作最少。 我希望這有幫助。
盡管這不是確定性的預期行為。 問題在於在EventLoopScheduler
設置了第二個訂閱。 花費一些時間來設置要由調度程序觀察的訂閱。 但是它的通知已經在主線程中進行了。 到建立訂閱時,循環將完成執行。
若要查看此情況,請從事件主題中刪除ObserveOn
。 這將強制設置訂閱,然后繼續使用值通知第二個主題。 您還可以在OnNext(true)
之后等待一段時間,以允許其連接訂閱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.