0

特定のスレッドでオブザーバーを適切に動作させるのに問題があります。

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 を用意しました。

問題は、値のサブスクリプションから何も得られないことです。

ここで、生成ループ (OnNext の後) に Thread.Sleep(10) を追加すると、完全に正常に動作します。だから私は自分が間違っていることにちょっと当惑しており、助けやアドバイスをくれてとても感謝しています。

4

2 に答える 2

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 つしかなく、そのサブスクリプションで最小限の量の作業を行います。これが役立つことを願っています。

于 2012-09-10T00:23:57.693 に答える
2

これは非決定論的ですが、予想される動作です。問題は、2 番目のサブスクリプションが で設定されていることEventLoopSchedulerです。スケジューラーによって監視されるようにサブスクリプションをセットアップするには、少し時間がかかります。しかし、その通知はメインスレッドですでに進行中です。サブスクリプションが設定されるまでに、ループの実行は終了します。

これが起こっていることを確認するにObserveOnは、イベントの件名から を削除してください。これにより、2 番目のサブジェクトに値を通知する前にサブスクリプションが強制的に設定されます。OnNext(true)サブスクリプションを接続できるように、 の後にしばらく時間が経過するのを待つこともできます。

于 2012-09-09T08:18:23.190 に答える