2012-01-24 19 views
6

.net Observableクラスを使用して単純なオブザーバーパターンを実装しようとしています。私はこのようなコードがあります。.net Observable ObserveOnバックグラウンドスレッド

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "FirstName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnFirstNameChanged(search.EventArgs)); 

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "LastName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnLastNameChanged(search.EventArgs)); 

私はオブザーバーは、バックグラウンドスレッドで実行したいが、私は(私たちの本当の実装のために、それがあまりにも複雑になり、同じバックグラウンドスレッド上のすべての実行するようにしたいです別のスレッドにすべてのリスナーを持つ)。

つまり、UIスレッド以外のスレッドでOnXXXChangedロジックをすべて実行したいのですが、スレッドプール全体でObservingの代わりに、同じスレッドで正しい順序で実行されていることを確認します。

上記はどのように修正する必要がありますか?

さらに、このパターンを実装するために、Observableクラスを使用したサンプルコードのサンプルがありますか?

答えて

13

あなたはEventLoopSchedulerを作成し、ObserverOnへのすべての呼び出しで、その単一インスタンスを使用する必要があります。

var scheduler = new EventLoopScheduler(ts => new Thread(ts)); 

... .ObserveOn(scheduler). ... 

ファクトリメソッドによって作成されたスレッドは、上の実行をスケジュールするために使用するスレッドです。 ExitIfEmptyfalseに設定すると、この呼び出しはすべての呼び出しで再利用されるという意味がない場合でも終了しません。

ただし、Scheduler.NewThreadを使用することもできます。そのスケジューラを使用することで、何もする必要がなければスレッドを終了させることができます。 ObserverOnにより多くの作業がキューイングされると、新しいスレッドが作成されますが、異なるオブザーバを同期させていないという意味で単一のスレッドしか存在しません。

EventLoopSchedulerScheduler.NewThreadによって使用される)によって作成されたスレッドは、Event Loop #という名前です。これらの名前はデバッガに表示されます。

+0

大変ありがとうございました! – user981225

+1

EventLoopSchedulerはIDisposableを実装していますので、処理を担当します。観察可能なファクトリを使用するメソッドを使用して、生涯をサブスクリプションに結びつけることができます。 – Fredrick

+0

Scheduler.NewThreadは廃止されました。代わりにNewThreadScheduler.Defaultを使用する必要があります。 – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool)は、観測が実行されるスレッドを指示するスレッドスケジューラをとります。 ThreadPoolではなく、EventLoopSchedulerを使用する単一スレッドのように見えます。

+0

ありがとうございます! – user981225

+0

Scheduler.ThreadPoolは廃止されました – liang

関連する問題