Reactive Extensions を使用すると、 を使用してイベントを簡単にサブスクライブObservable.FromEventPattern
できますが、IObservable
.
私の状況は次のとおりです。イベントを含むインターフェースを実装する必要があります。そのイベントは、オブジェクトの特定の値が変更されるたびに呼び出されることになっています。スレッドの安全性の理由から、特定の でこのイベントを呼び出す必要がありますSynchronizationContext
。また、登録時に現在の値を使用して各イベント ハンドラーを呼び出すことになっています。
public interface IFooWatcher
{
event FooChangedHandler FooChanged;
}
私が望むことを行うオブザーバブルを取得することは、Rxを使用してかなり簡単です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 { /* ??? */ }
}
}
add
ここで、 and関数を onとして渡されたものremove
をサブスクライブおよびサブスクライブ解除する簡単な方法を探しています。私の現在の実装は次のようになります。FooChangedHandler
Observer<Foo>
m_observable
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();
}
}
ただし、これらのイベントのいくつか (異なるハンドラー タイプ) を実装する必要があるため、より簡単な解決策を見つけたいと考えています。私は独自の一般的なソリューションを展開しようとしましたが、回避する必要があるいくつかの追加の問題が発生します (特に、のパラメーターを受け取るデリゲートを一般的に操作する方法T
)。この方向のギャップ -FromEventPattern
逆も同様です。