2011-11-14 26 views
6

Tôi có một sự kiện mà tôi không kiểm soát được trong đó cung cấp cho tôi dữ liệu. EventArgs trông giống như sau:Làm thế nào để hoàn thành một Rx Observable tùy thuộc vào một điều kiện trong một sự kiện

class MyEventArg { 
    bool IsLastItem {get;} 
    Data DataItem {get;} 
} 

Tôi sử dụng Rx để chuyển sự kiện này thành IObservable. Nhưng tôi muốn hoàn thành việc quan sát nếu IsLastItem là sự thật.

Bất kỳ ý tưởng thanh lịch nào? Có một cách để phân loại dữ liệu thông qua một chủ đề mà tôi có nhiều quyền kiểm soát hơn để đặt sự kiện OnComplete nếu điều kiện xảy ra ...

Trả lời

9

Nếu bạn muốn phần tử cuối cùng được đưa vào, bạn có thể hợp nhất luồng chỉ với phần tử cuối cùng cùng với luồng thông thường kết hợp với TakeWhile. Đây là một ứng dụng giao diện điều khiển đơn giản để chứng minh điều đó:

var subject = new List<string> 
{        
"test", 
"last" 
}.ToObservable(); 

var my = subject 
      .Where(x => x == "last").Take(1) 
      .Merge(subject.TakeWhile(x => x != "last")); 

my.Subscribe(
    o => Console.WriteLine("On Next: " + o), 
    () => Console.WriteLine("Completed")); 

Console.ReadLine(); 

in này:

On Next: test 
On Next: last 
Completed 

CẬP NHẬT Có một lỗi mà supressed thông điệp OnCompleted nếu Quan sát cơ bản không thực sự hoàn chỉnh . Tôi sửa lại đoạn code để đảm bảo OnCompleted được gọi

Và nếu bạn muốn tránh đăng ký vào các chuỗi cơ bản nhiều lần cho quan sát lạnh bạn có thể cấu trúc lại các mã như thế này:

var my = subject.Publish(p => p 
      .Where(x => x == "last").Take(1) 
      .Merge(p.TakeWhile(x => x != "last"))); 
+0

Rất tuyệt! Đã cho tôi một vài giây để xem làm thế nào nó được thực hiện. Có thể viết tốt hơn: subject.TakeWhile (x => x! = "Last"). Merge (subject.Where (x => x == "last") Lấy (1)); Mẹo quan sát được lạnh là +. Cảm ơn – lukebuehler

2

Bạn đang tìm kiếm một cái gì đó như thế này?

IObservable<MyEventArg> result = 
    myEventArgObservable.TakeWhile(arg => !arg.IsLastItem); 
+0

Wow, mà có thể đơn giản và tốt đẹp. Bạn có biết liệu Observable có thể hoàn thành nếu vị từ là đúng không? – lukebuehler

+0

Có, nó sẽ thông báo cho OnCompleted() nếu bạn không muốn nó thông báo OnCompleted bạn chỉ có thể sử dụng Where (arg =>! Arg.IsLastItem) – Christoph

+1

Có, có vẻ như Observable đã hoàn thành, NHƯNG bây giờ tôi có vấn đề Tôi sẽ không nhận được món hàng cuối cùng ... – lukebuehler

2
public static IObservable<TSource> TakeWhileInclusive<TSource>(
     this IObservable<TSource> source, Func<TSource, bool> predicate) 
{ 
    return Observable 
     .Create<TSource>(o => source.Subscribe(x => 
                { 
                 o.OnNext(x); 
                 if (!predicate(x)) 
                  o.OnCompleted(); 
                }, 
               o.OnError, 
               o.OnCompleted 
           )); 
} 
Các vấn đề liên quan