2016-02-12 22 views
5

Làm cách nào tôi có thể hủy loại Rx quan sát được sau đây, nếu có thể quan sát được sau đây trên một nút StartButton, tức là từ nút dừng.Mã thông báo hủy cho quan sát được

var instance = ThreadPoolScheduler.Instance; 

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

Trả lời

10

Chỉ cần sử dụng một trong những định nghĩa chồng cho Subscribe mà phải mất một CancellationToken:

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

này đơn giản hóa ví dụ Jon Skeet:

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

Đẹp, chưa từng thấy điều đó. (Cả hai công việc, tất nhiên ... Tôi nghi ngờ rằng quá tải theo dõi chỉ cần gọi đăng ký trong cùng một cách :) –

+0

@ JonSkeet Có, tất cả các phương pháp mở rộng CancellationToken làm là đăng ký Vứt bỏ như bạn đã làm. –

9

Bạn giữ IDisposable đã được trả về bởi Subscribe, và gọi Dispose trên đó.

Cũng có thể là cách tích hợp Rx IDisposable dựa trên đăng ký hủy đăng ký với CancellationToken ra khỏi hộp, nhưng chỉ cần gọi Dispose sẽ là khởi đầu. (Bạn có thể luôn luôn chỉ cần đăng ký một sự tiếp nối với các dấu hiệu hủy để gọi vứt bỏ ...)

Dưới đây là một ví dụ ngắn nhưng đầy đủ để chứng minh:

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! Chúng tôi có một người chiến thắng, chính xác những gì tôi đã sau, chúc mừng @Jon – Mdev

+0

Tôi thích rằng bạn lén lút thay thế DateTime.Now với DateTime.UtcNow :) –

+0

Khi tôi nhìn vào một câu hỏi tương tự, tôi bối rối vì sao Microsoft không đơn giản làm OnNext có kiểu trả về bool. Điều đó có thể chỉ có nghĩa là tiếp tục hay không. Sau đó, các mã xử lý có thể (vì nó thấy phù hợp) chỉ trả về false khi nó được thực hiện. – Hugh

Các vấn đề liên quan