2016-02-12 66 views
5

如果在StartButton單擊中,即從停止按鈕創建以下可觀察項,我如何取消以下類型的Rx Observable。可觀察的取消令牌

var instance = ThreadPoolScheduler.Instance; 

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

回答

10

只需使用的Subscribe,需要一個重載的一個CancellationToken

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

這簡化喬恩斯基特的例子:

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

不錯,沒有見過。 (當然兩者都有效......我懷疑Subscribe重載只是以相同的方式調用寄存器:) –

+0

@JonSkeet是的,所有CancellationToken擴展方法所做的就是像註冊一樣註冊Dispose。 –

9

您保留,是由Subscribe返回IDisposable,並在其上調用Dispose

很可能有一種方法可以將基於Rx IDisposable的取消訂閱與CancellationToken開箱即用,但只需撥打Dispose即可。 (你總是可以只註冊一個延續與取消標記調用dispose ...)

下面是一個簡短但完整的例子來說明:

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

賓果!我們有一個贏家,正是我以後的樣子,歡呼@Jon – Mdev

+0

我喜歡你偷偷地用DateTime.UtcNow替換DateTime.Now :) –

+0

我自己也在看類似的問題,我很疑惑爲什麼微軟不會簡單地製作OnNext有一個返回類型的布爾值。那可能只是意味着是否繼續。然後,處理代碼可以(如果合適)在完成時返回false。 – Hugh

相關問題