Các Extensions phản ứng cho phép bạn dễ dàng đăng ký vào một sự kiện sử dụng Observable.FromEventPattern
, nhưng tôi không thể tìm thấy bất cứ điều gì về cách bạn có thể thực hiện một sự kiện khi bạn có một IObservable
.Làm thế nào để thực hiện một sự kiện sử dụng phản ứng Extensions
Tình huống của tôi là: Tôi cần triển khai giao diện chứa sự kiện. Sự kiện đó được cho là được gọi bất cứ khi nào một giá trị nhất định của đối tượng của tôi thay đổi và vì lý do an toàn chủ đề, tôi cần phải gọi sự kiện này trên một số SynchronizationContext
nhất định. Tôi cũng phải gọi mỗi người xử lý sự kiện với giá trị hiện tại khi đăng ký.
public interface IFooWatcher
{
event FooChangedHandler FooChanged;
}
Bắt một quan sát được rằng những gì tôi muốn là khá dễ dàng với Rx sử dụng BehaviorSubject
:
public class FooWatcher
{
private readonly BehaviorSubject<Foo> m_subject;
private readonly IObservable<Foo> m_observable;
public FooWatcher(SynchronizationContext synchronizationContext, Foo initialValue)
{
m_subject = new BehaviorSubject<Foo>(initialValue);
m_observable = m_subject
.DistinctUntilChanged()
.ObserveOn(synchronizationContext);
}
public event FooChangedHandler FooChanged
{
add { /* ??? */ }
remove { /* ??? */ }
}
}
Bây giờ tôi đang tìm kiếm một cách dễ dàng để có add
và remove
chức năng đăng ký và huỷ đăng ký các thông qua FooChangedHandler
dưới dạng Observer<Foo>
trên m_observable
. Triển khai hiện tại của tôi trông giống như sau:
add
{
lock (m_lock)
{
IDisposable disp = m_observable.Subscribe(value);
m_registeredObservers.Add(
new KeyValuePair<FooChangedHandler, IDisposable>(
value, disp));
}
}
remove
{
lock (m_lock)
{
KeyValuePair<FooChangedHandler, IDisposable> observerDisposable =
m_registeredObservers
.First(pair => object.Equals(pair.Key, value));
m_registeredObservers.Remove(observerDisposable);
observerDisposable.Value.Dispose();
}
}
Tuy nhiên, tôi hy vọng sẽ tìm thấy một giải pháp dễ dàng hơn, vì tôi cần triển khai một số sự kiện này (với các loại trình xử lý khác nhau). Tôi đã cố gắng tung ra giải pháp chung của riêng mình nhưng nó tạo ra một số vấn đề cần phải làm việc xung quanh (đặc biệt, cách bạn làm việc chung với một đại biểu có tham số T
), vì vậy tôi muốn tìm giải pháp hiện có khoảng cách theo hướng này - cũng giống như FromEventPattern
làm ngược lại.
Cảm ơn, tôi đã không nhìn thấy 'ToEvent()' trước đây! Đây là một phần lớn của câu đố. Việc chuyển đổi giữa 'Action' và 'FooChangedHandler' vẫn là một vấn đề (vâng, tiếc là chúng ta đang mắc kẹt với những điều này).Vấn đề: Các đại biểu là bình đẳng nếu họ có cùng đích và phương pháp, nhưng bình đẳng này chỉ đạt tới một cấp - nếu bạn có một đại biểu và bọc nó trong hai trường hợp 'Action ' riêng biệt, chúng sẽ bằng nhau, nhưng nếu bạn quấn cả hai 'Hành động ' các trường hợp khác 'Hành động ' mỗi, * những * sẽ * không * bằng nhau. Tuy nhiên, tôi nghĩ rằng tôi đã thấy một giải pháp cho điều này rồi ... –
Medo42
Ah vâng, đây là: http://stackoverflow.com/a/9290684/575615 Tôi sẽ thử nghiệm vào ngày mai, cảm ơn một lần nữa! – Medo42
Mọi thứ hoạt động như mong đợi ngay bây giờ. Sử dụng một giải pháp giống như một giải pháp được liên kết ở trên để chuyển đổi các đại biểu thành 'Action' cho phép tôi viết một giải pháp chung ngắn gọn và ngọt ngào làm việc với 'ToEvent()' nội bộ. Không có nhiều thứ trong lớp đó, nhưng tôi muốn gộp cả 'Subject' và' IEventSource' lại thành một đối tượng. –
Medo42