2016-05-10 12 views
6

Tôi có Observable.Interval(TimeSpan.FromSeconds(1)) và một thuê bao kiểm tra thứ gì đó trong DB mỗi khoảng thời gian xảy ra. Nhưng đôi khi khi tôi làm điều đó kiểm tra từ DB tôi muốn ngay lập tức thực hiện một kiểm tra khác (gọi thuê bao đó một lần nữa bởi vì tôi biết có cái gì đó trong hàng đợi).Phản ứng - Kết hợp khoảng thời gian quan sát được với các bộ kích hoạt thủ công

tôi đã được quản lý để đạt được một cái gì đó tương tự bằng cách kết hợp với Interval while bên trong phương pháp thuê bao:

Observable    
.Interval(TimeSpan.FromSeconds(1)) 
.Sample(TimeSpan.FromSeconds(1)) //to avoid multiple 'stacked' intervals 
.Subscribe(RepeatAction); 


private void RepeatAction(long _) 
{ 
    bool wasSuccess; 
    do 
    { 
     wasSuccess = CheckingInDB(); //Long operation 
    } while (wasSuccess); 
} 

Nhưng là nó có thể đạt được điều đó loại hành vi với tinh khiết phản ứng?

+1

Phương thức 'SubscribeInContext' là gì? Cái đó từ đâu? – Enigmativity

Trả lời

3

Có. Điều đó là có thể.

Đầu tiên, mặc dù có một sự hiểu lầm mà bạn có với Rx.

Nếu bạn chạy mã này:

void Main() 
{ 
    Observable 
     .Interval(TimeSpan.FromSeconds(1.0)) 
     .Sample(TimeSpan.FromSeconds(1.0)) 
     .Timestamp() 
     .Subscribe(RepeatAction); 
} 

private void RepeatAction(Timestamped<long> _) 
{ 
    Console.WriteLine(_.Timestamp); 
    Thread.Sleep(10000); 
} 

Bạn sẽ nhận được kết quả này:

2016/05/11 10:37:57 +00:00 
2016/05/11 10:38:07 +00:00 
2016/05/11 10:38:17 +00:00 
2016/05/11 10:38:27 +00:00 

Bạn sẽ thấy rằng các bước giữa mỗi giá trị được sản xuất là 10 giây, không 1. Toán tử Interval chỉ đơn giản đảm bảo rằng khoảng cách giữa mỗi giá trị là ít nhất thời lượng của TimeSpan, nhưng nếu người quan sát mất nhiều thời gian hơn thì thời lượng càng dài càng tốt. Nó không xếp hàng các giá trị.

Một cách khác để xem xét là .Sample(TimeSpan.FromSeconds(1)) không có gì là .Interval(TimeSpan.FromSeconds(1.0)) đảm bảo rằng khoảng cách tối thiểu giữa các giá trị đã là 1 giây.

Bây giờ, để giải quyết vấn đề bằng cách sử dụng các toán tử Rx thuần túy. Hãy thử điều này:

var query = 
    Observable 
     .Interval(TimeSpan.FromSeconds(1.0)) 
     .Select(_ => 
      Observable 
       .While(
        () => CheckingInDB(), 
        Observable.Return(Unit.Default))) 
     .Switch(); 

Điều này sẽ thử mỗi giây để kiểm tra cơ sở dữ liệu, nhưng khi nó đạt giá trị, nó sẽ nhanh chóng lặp lại séc cho đến khi nó không. Sau đó, nó chờ đợi 1 giây và thử lại.

+0

Cảm ơn câu trả lời của bạn, nó có vẻ hợp lý nhưng tôi không thể làm cho nó hoạt động được. Nó không bao giờ bắn CheckingInDb(). Bất kỳ ý tưởng? –

+0

@Knopo - Tôi vừa thử nghiệm truy vấn của mình bằng cách sao chép và dán vào trong môi trường dev của tôi và nó hoạt động tốt khi gọi 'CheckingInDB' như mong đợi. Hãy thử chỉ cần thực hiện một 'CheckingInDB' rất đơn giản và xem điều gì sẽ xảy ra? Của tôi là 'public bool CheckingInDB() {Console.WriteLine ("! "); trả lại đúng; } '. – Enigmativity

+1

@Knopo - Bạn đã đăng ký theo dõi, đúng không? – Enigmativity

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