2016-06-16 6 views
0

私は新しいスレッドでオブザーバブルをスケジュールし、その結果を現在のスレッドに戻そうとしています。現在のスレッドに戻る

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Log("init"); 

      Observable.Return(0) 
       .ObserveOn(NewThreadScheduler.Default) 
       .Do(_ => Log("Do1 method")) 
       .ObserveOn(CurrentThreadScheduler.Instance) 
       .Do(_ => Log("Do2 method")) 
       .Subscribe(_ => Log("subscribe method")); 

      Console.ReadKey(); 
     } 

     static void Log(string label) 
     { 
      Console.WriteLine("{0} on {1}", label, Thread.CurrentThread.ManagedThreadId); 
     } 
    } 
} 

これは私が取得していた結果である:

init on 9 
Do1 method on 10 
Do2 method on 10 
subscribe method on 10 

はなぜDo2にする方法と購読方法は、代わりに#9のスレッド#10にあるのでしょうか?私はこの結果を期待していた。

init on 9 
Do1 method on 10 
Do2 method on 9 
subscribe method on 9 

答えて

2

私はあなたが達成しようとしているかを見ることができますが、あなただけの同期スレッドのコンソールアプリで実行されている、これは難しいかもしれ。 メインコンソールスレッドはEventLoopではないので、RxはConsole.ReadKey()コールを「ブロック解除」するだけで、スレッドをハイジャックしてLogメソッドを実行してから、Console.ReadKey()に待機を返しますか?

GUIアプリケーションでこれを行っていた場合、メインスレッドはEventLoopのようなものになります。つまり、WPF/Silverlightのディスパッチャです。 これは "メインスレッド"に戻って制御を戻すことが容易になりました - ObserveOn(_dispatcherScheduler)_dispatcherSchedulerDispatcherSchedulerのキャプチャされたインスタンスです。

ImmediateCurrentスケジューラの説明はこちら - http://introtorx.com/Content/v1.0.10621.0/15_SchedulingAndThreading.html#SchedulersIndepthです。

あなたの元のコードの代わりに、完全に名付けられ、以下の(予想)出力を作成しますEventLoopScheduler

void Main() 
{ 
    var els = new EventLoopScheduler(ts => new Thread(ts) { IsBackground = true, Name = "MyEventLoopThread"}); 
    els.Schedule(0, (scheduler, _)=>Run(scheduler)); 
} 
static IDisposable Run(IScheduler mainThreadScheduler) 
{ 
    Log("init"); 
    return Observable.Return(0) 
     .ObserveOn(NewThreadScheduler.Default) 
     .Do(_ => Log("Do1 method")) 
     .ObserveOn(mainThreadScheduler) 
     .Do(_ => Log("Do2 method")) 
     .Subscribe(_ => Log("subscribe method")); 
} 
static void Log(string label) 
{ 
    Console.WriteLine("{0} on {1}", label, Thread.CurrentThread.ManagedThreadId); 
} 

init on 28 
Do1 method on 29 
Do2 method on 28 
subscribe method on 28 
+0

おかげで使用してイベントループとして機能する第三のスレッドを実行することができロット!私のアプリは正常に動作していましたが、私はコンソールプロジェクトでそれを再現しませんでした。 – goodfriend0

関連する問題