簡體   English   中英

反應式擴展中的嵌套訂閱

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM