2017-08-13 1 views
2

投稿した件名に記載されている内容を達成するために、以下のコードを書くより良い方法はありますか?Observable SubscriptionをキャンセルしてObserverが終了するのを待つ

Subject<long>を使用すると、次のコードが複雑すぎたり、冗長すぎたりします。一般的なソリューションを作成することは容易ではありません。

var subject = new Subject<long>(); 
var cts = new CancellationTokenSource(); 
var observable = Observable.Interval(TimeSpan.FromSeconds(2)); 
var disposable = observable.Do(l => { 
    { 
     Console.WriteLine($"Start {l}-{DateTime.Now}"); 
     Thread.Sleep(2000); 

     Console.WriteLine($"Stop {l}-{DateTime.Now}"); 
     subject.OnNext(l); 
    } 
}).Subscribe(); 
cts.Token.Register(disposable.Dispose); 

Thread.Sleep(5000); 
subject.Subscribe(); 
cts.Cancel(); 
subject.FirstAsync().Wait(); 

Console.WriteLine("Finish"); 

答えて

3

あなたはSubject<Unit>が完了したことを知らせるために使用してコードを書く方がいいでしょうことなく、同じ出力を生成完了後の自動廃棄してください。 boolの配列を使用するのはちょっと面倒なので、マルチスレッドコードでこのようなテクニックを使用すると悲しみを引き起こす可能性があります。

これを試してみてください:

var observable = Observable.Interval(TimeSpan.FromSeconds(2)); 
Subject<Unit> finish = new Subject<Unit>(); 
observable 
    .TakeUntil(finish) 
    .Do(l => 
    { 
     Console.WriteLine($"Start {l}-{DateTime.Now}"); 
     Thread.Sleep(2000); 
     Console.WriteLine($"Stop {l}-{DateTime.Now}"); 
    }) 
    .Finally(() => Console.WriteLine("Finally")) 
    .Subscribe(
     l => Console.WriteLine("OnNext"), 
     () => Console.WriteLine("Complete")); 

Thread.Sleep(5000); 
finish.OnNext(Unit.Default); 
Console.ReadLine(); 

それが生成する:私は完全に同意した

 
Start 0-2017/08/15 13:37:03 
Stop 0-2017/08/15 13:37:05 
OnNext 
Start 1-2017/08/15 13:37:05 
Stop 1-2017/08/15 13:37:07 
OnNext 
Complete 
Finally 
+0

、私はすでに、それは私の自己を発見するが、あなたはupvoteに値します –

0

実際にサブスクリプションをキャンセルすると、それ以上のシグナリングは行われません。正しいことは、完了を待つことです。それ以上の処理は

 var observable = Observable.Interval(TimeSpan.FromSeconds(2)); 
     bool[] finish = {false}; 
     observable.TakeWhile(l => !finish[0]).Do(l => { 
      Console.WriteLine($"Start {l}-{DateTime.Now}"); 
      Thread.Sleep(2000); 
      Console.WriteLine($"Stop {l}-{DateTime.Now}"); 

     }).Finally(() => Console.WriteLine("Finally")).Subscribe(l => { 
      Console.WriteLine("OnNext"); 
     },() => Console.WriteLine("Complete")); 
     finish[0] = true; 
     Console.ReadKey(true); 

を必要としないので、サブスクリプションは、上記の余分な対象

関連する問題