2012-07-12 8 views
13

Giả sử tôi muốn tạo ra một luồng không đồng bộ các số ngẫu nhiên sẽ bơm ra một giá trị mới sau mỗi 100 mili giây. Trong khi cố gắng tìm ra giải pháp, nỗ lực đầu tiên của tôi trông giống như sau:Observable.Defer - cần làm rõ một số để biết chính xác nó làm gì

 var random = new Random(); 
     Observable.Start(() => random.Next()) 
        .Delay(TimeSpan.FromMilliseconds(100)) 
        .Repeat() 
        .Subscribe(Console.WriteLine); 

Nếu bạn thử và chạy nó, bạn sẽ nhận thấy rằng nó chỉ lặp lại giá trị đó lặp đi lặp lại. OK, tôi đoán tôi hiểu lầm cách lặp lại hoạt động. Sau khi chơi đùa một chút, tôi đến với điều này và nó làm việc:

 var random = new Random(); 
     Observable.Defer(()=> Observable.Start(() => random.Next())) 
        .Delay(TimeSpan.FromMilliseconds(100)) 
        .Repeat() 
        .Subscribe(Console.WriteLine); 

Vì vậy, tôi đã đi đến tài liệu MSDN để hiểu những gì Hoãn được thực sự làm, và đây là những gì nó nói:

Trả về một chuỗi có thể quan sát để gọi nhà máy quan sát bất cứ khi nào một người quan sát mới đăng ký.

Tôi đoán nhầm lẫn của tôi là thế này: trong mẫu mã của tôi, tôi chỉ từng đăng ký vào các Quan sát một lần, vậy tại sao là nó dường như cách gọi các Observable.Start(...) hơn và hơn? Hay tôi hiểu nhầm Repeat()? Bất kỳ làm rõ sẽ là tuyệt vời.

Trả lời

17

Bạn đang hiểu lầm Lặp lại. Về cơ bản, Lặp lại sẽ tiếp tục đăng ký lại một lần có thể quan sát mỗi lần hoàn thành.

Quan sát.Bắt đầu dường như lưu trữ giá trị trong lần đầu tiên bạn gọi Đăng ký và trả lại giá trị đó mỗi khi bạn đăng ký. Đây là những gì gây ra cùng một số hơn và hơn trong ví dụ đầu tiên.

Hoãn làm việc gì đó như thế này:

IObservable<T> Defer(Func<IObservable<T>> factory) 
{ 
    return Observable.Create<T>(obs => factory().Subscribe(obs)); 
} 

nên mỗi khi bạn đăng ký vào Defer thể quan sát được, nó phải gọi factory chức năng. Trong trường hợp này, nhà máy tạo một mới có thể quan sát được, do đó tránh được hoạt động bộ nhớ đệm của Start.

Cách khác để nhận chuỗi bạn mô tả là sử dụng Interval để nhận thời gian và Select để nhận số ngẫu nhiên.

Observable.Interval(TimeSpan.FromMilliseconds(100)) 
      .Select(i => random.Next()) 
      .Subscribe(Console.WriteLine); 
5

Cách đơn giản để "tạo" số ngẫu nhiên là sử dụng .Generate. Hãy thử điều này:

var rnd = new Random(); 

Observable 
    .Generate(
     0, 
     x => true, 
     x => x, 
     x => rnd.Next(), 
     x => TimeSpan.FromMilliseconds(100.0)) 
    .Subscribe(n => { });