2

私が作業している Silverlight アプリケーションで、非常に奇妙な動作が発生しています。次のコードを参照してください。

var replaySubject = new ReplaySubject<string>(1);
    replaySubject.OnNext("This can never block... surely?");

var s = replaySubject.First();
Debug.WriteLine(s);

基本的に、私のアプリはこのコードを繰り返し通過し、常にメッセージを出力します...ただし、スレッドがFirst()回線上でブロックされる特定のシナリオを除きます。

これは常に UI スレッドにあります。で行にブレークポイントを設定し、デバッガーでFirst()ドリルダウンすると、キューに文字列が表示されます。replaySubject

First()ここで呼び出しがブロックされるシナリオを考えられる人はいますか?

ところで: それは RX バージョン 1.1.11111 です

4

2 に答える 2

3

ReplaySubjectでは、デフォルトでScheduler.CurrentThread.

またはReplaySubjectを使用するように明示的に設定すると、期待どおりに動作します。Scheduler.ImmediateScheduler.ThreadPool

var replaySubject = new ReplaySubject<string>(1, Scheduler.Immediate);
    replaySubject.OnNext("This can never block... surely?");

var s = replaySubject.First();
Debug.WriteLine(s);

特定のシナリオで UI スレッドがこの混乱にどのように陥っているかを調査する必要がありますが、今のところ、これで問題は解決しています。

--- 編集 ---

OK、さらに調査すると、ほとんどの場合、上記のコードは ThreadPool スレッドで開始されることがわかりました。コードに到達したときは Dispatcher スレッド上にありますが、Scheduler.CurrentThread は ReplaySubject を元の ThreadPool スレッドに戻します。

ただし、壊れているシナリオでは、ユーザーがボタンをクリックすることからすべてが始まります。これは明らかに UI スレッド上にあり、このコード部分に到達すると、Scheduler.CurrentThread が UI スレッドになり、既に UI スレッド上にあるため、デッドロックが発生します。最初は ReplaySubject がポンプするのを待っていますが、ポンプは現在のアクションの後ろでキューに入れられています。微妙で、注意すべきこと。

于 2012-11-07T15:14:33.377 に答える
0

あなたのコードから、これに登録されているサブスクライバーがないようObservableです。そのため、利用可能な最初のものを提供できるように、サブスクライブするのを待つ場合があります。

FirstOrDefault代わりに、空かどうかを確認してみてください。

于 2012-11-07T13:40:52.037 に答える