2012-01-24 14 views
6

Sto cercando di implementare un semplice pattern Observer utilizzando la classe .net Observable. Ho codice che assomiglia a questo:.net Osservabile "ObserveOn" a thread di sfondo

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)); 

Voglio gli osservatori per l'esecuzione su un thread in background, ma li voglio tutti corrono sullo stesso thread in background (per la nostra implementazione reale, sarà troppo complicato avere ogni ascoltatore su un thread diverso).

cioè voglio tutta la OnXXXChanged logica da eseguire su un thread diverso dal thread UI, ma invece di Observing sull'intero threadpool, voglio assicurarsi che vengano eseguite nell'ordine corretto, sullo stesso filo.

Come deve essere modificato quanto sopra?

Inoltre, su una nota in qualche modo correlata, esistono esempi di codice di esempio validi che utilizzano la classe Observable per implementare questo modello?

risposta

13

è necessario creare un EventLoopScheduler e uso che solo caso in tutte le chiamate a ObserverOn:

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

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

Il filo creato dal metodo factory è il filo utilizzato per pianificare l'esecuzione su. Se si lascia la proprietà ExitIfEmpty impostata su false, questa discussione non verrà interrotta anche se non c'è nulla da fare, il che significa che sarà riutilizzata per ogni chiamata.

Tuttavia, si potrebbe anche considerare l'utilizzo di Scheduler.NewThread. L'utilizzo di questo programma di pianificazione consentirà la terminazione del thread se non c'è più nulla da fare. Quando più lavori vengono messi in coda da ObserverOn, verrà creato un nuovo thread, ma solo un singolo thread dovrebbe mai esistere, ovvero non è possibile sincronizzare osservatori diversi.

I fili creato da EventLoopScheduler (che viene utilizzato da Scheduler.NewThread) sono denominati Event Loop #. Vedrai questi nomi nel debugger.

+0

Grande, grazie mille! – user981225

+1

EventLoopScheduler implementa IDisposable in modo da essere responsabile della sua eliminazione. È possibile utilizzare il metodo Using osservable factory per collegare la durata all'abbonamento. – Fredrick

+0

Scheduler.NewThread è deprecato adesso, dovresti usare NewThreadScheduler.Default. – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool) utilizza uno scheduler di thread che detta il thread su cui viene eseguita l'osservazione. Sembra un singolo thread che si desidera utilizzare EventLoopScheduler anziché ThreadPool.

+0

Grazie mille! – user981225

+0

Scheduler.ThreadPool è stato reso obsoleto – liang

Problemi correlati