2016-02-12 18 views
5

Wie kann ich den folgenden Typ von Rx Observable abbrechen, wenn die folgende Observable bei einem StartButton-Klick erstellt wird, d. H. Von einer Stop-Schaltfläche.Cancelation Token für beobachtbare

var instance = ThreadPoolScheduler.Instance; 

Observable.Interval(TimeSpan.FromSeconds(2), instance) 
        .Subscribe(_ => 
        { 
        Console.WriteLine(DateTime.Now); // dummy event 
        } 
        );   

Antwort

10

eine Gerechter Gebrauch der Überlastung von Subscribe, die eine nimmt CancellationToken:

observable.Subscribe(_ => Console.WriteLine(DateTime.UtcNow), cancellationToken); 

Dieses Beispiel Jon Skeet vereinfacht:

using System; 
using System.Reactive.Concurrency; 
using System.Reactive.Linq; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var instance = ThreadPoolScheduler.Instance; 
     var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); 

     Observable.Interval(TimeSpan.FromSeconds(0.5), instance) 
      .Subscribe(_ => Console.WriteLine(DateTime.UtcNow), cts.Token); 
     Thread.Sleep(10000); 
    } 
} 
+0

Schön, hatte das nicht gesehen. (Beide arbeiten, natürlich ... Ich vermute, dass die Abonnieren Überlastungen rufen Sie einfach auf die gleiche Art und Weise registrieren :) –

+0

@JonSkeet Ja, alle CancellationToken Erweiterungsmethoden tun, ist registrieren Entsorgen wie Sie haben. –

9

Sie behalten die IDisposable, die von Subscribe zurückgegeben wurde, und Dispose auf es nennen.

Es kann gut sein, eine Möglichkeit, die Rx IDisposable -basierte Abmelde der Integration mit CancellationToken aus der Box, aber nur Dispose ruft ein Anfang wäre. (Sie können immer nur eine Fortsetzung des Widerruf Token registrieren zu nennen verfügen ...)

Hier ist ein kurzes, aber vollständiges Beispiel zu demonstrieren:

using System; 
using System.Reactive.Concurrency; 
using System.Reactive.Linq; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var instance = ThreadPoolScheduler.Instance; 
     var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); 

     var disposable = Observable 
      .Interval(TimeSpan.FromSeconds(0.5), instance) 
      .Subscribe(_ => Console.WriteLine(DateTime.UtcNow)); 
     cts.Token.Register(() => disposable.Dispose()); 
     Thread.Sleep(10000); 
    } 
} 
+0

Bingo! Wir haben einen Gewinner, genau das, was ich suchte, jubelt @Jon – Mdev

+0

Ich mag, dass Sie DateTime.Now mit DateTime.UtcNow heimlich ersetzt. –

+0

Als ich mir eine ähnliche Frage anschaue, bin ich verwirrt, warum Microsoft nicht einfach gemacht hat OnNext haben einen Rückgabetyp von bool. Das könnte dann einfach weitergehen oder nicht. Dann könnte der Bearbeitungscode (wie er es für richtig hält) einfach falsch zurückgeben, wenn es fertig ist. – Hugh

Verwandte Themen