2012-01-24 6 views
6

Tôi đang cố triển khai một mẫu Observer đơn giản bằng cách sử dụng lớp .net Observable. Tôi có mã trông như thế này:.net Quan sát 'Quan sát' một chủ đề nền

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "FirstName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnFirstNameChanged(search.EventArgs)); 

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "LastName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnLastNameChanged(search.EventArgs)); 

Tôi muốn các nhà quan sát để chạy trên một sợi nền, nhưng tôi muốn họ tất cả chạy trên thread cùng một nền (để thực hiện thực của chúng ta, nó sẽ là quá phức tạp để có mọi người nghe trên một chủ đề khác nhau).

tức là tôi muốn tất cả logic OnXXXChanged được thực hiện trên một chủ đề khác với chuỗi giao diện người dùng, nhưng thay vì Observing trên toàn bộ threadpool, tôi muốn đảm bảo chúng chạy đúng thứ tự, trên cùng một chuỗi.

Làm cách nào để sửa đổi các điều trên?

Ngoài ra, trên một lưu ý hơi liên quan, có bất kỳ ví dụ mã mẫu nào tốt bằng cách sử dụng lớp Observable để triển khai mẫu này không?

Trả lời

13

Bạn nên tạo một EventLoopScheduler và sử dụng trường hợp duy nhất trong tất cả các cuộc gọi đến ObserverOn:

var scheduler = new EventLoopScheduler(ts => new Thread(ts)); 

... .ObserveOn(scheduler). ... 

Các chủ đề được tạo ra theo phương pháp nhà máy là sợi dùng để sắp xếp việc thực hiện trên. Bằng cách rời khỏi thuộc tính ExitIfEmpty đặt thành false chuỗi này sẽ không chấm dứt ngay cả khi không có ý nghĩa gì để nó sẽ được sử dụng lại cho mọi cuộc gọi.

Tuy nhiên, bạn cũng có thể xem xét sử dụng Scheduler.NewThread. Sử dụng trình lên lịch đó sẽ cho phép chuỗi kết thúc nếu không có gì để thực hiện. Khi nhiều công việc được xếp hàng theo ObserverOn một chuỗi mới sẽ được tạo nhưng chỉ có một chuỗi duy nhất có thể tồn tại có nghĩa là bạn không đồng bộ hóa các nhà quan sát khác nhau.

Chủ đề được tạo bởi EventLoopScheduler (được sử dụng bởi Scheduler.NewThread) được đặt tên Event Loop #. Bạn sẽ thấy những tên này trong trình gỡ lỗi.

+0

Tuyệt vời, cảm ơn bạn rất nhiều! – user981225

+1

EventLoopScheduler triển khai IDisposable để bạn có trách nhiệm xử lý nó. Bạn có thể sử dụng phương thức Sử dụng nhà máy quan sát để gắn kết thời gian tồn tại cho đăng ký. – Fredrick

+0

Trình lập lịch biểu.NewThread không được dùng nữa ngay bây giờ, bạn nên sử dụng NewThreadScheduler.Default thay thế. – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool) có bộ lập lịch trình chỉ ra luồng mà quan sát sẽ chạy. Dường như cho một chuỗi đơn lẻ bạn muốn sử dụng EventLoopScheduler, thay vì ThreadPool.

+0

Cảm ơn bạn rất nhiều! – user981225

+0

Scheduler.ThreadPool đã bị lỗi thời – liang