を使用してイベントを実装するためにどのように反応性の拡張機能を使用すると、簡単に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
と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
と逆です。
ありがとうございました、私は前に 'ToEvent()'を見たことがありませんでした!これはすでにパズルの大きな部分です。 'Action'と 'FooChangedHandler'の間の変換はまだ問題です(残念ながら、私たちはこれらに固執しています)。問題:デリゲートが同じターゲットとメソッドを持っている場合、デリゲートは等しいですが、この等価性は1つのレベルにしか達しません。デリゲートを持ち、2つの別々の 'Action 'インスタンスにラップすると、それらのインスタンスは等しくなります。 'アクション'インスタンスはそれぞれ別の 'アクション'にあります。*これらは*等しくありません。しかし、私はこれについての解決策を既に見たと思います... –
Medo42
ああ、ここにありました:http://stackoverflow.com/a/9290684/575615私はこの明日、大きな感謝を再びテストします! – Medo42
すべてが期待通りに機能します。デリゲートを 'Action'に変換するための上記のようなソリューションを使用すると、' ToEvent() 'で内部的に動作する短くて甘いジェネリックソリューションを書くことができました。そのクラスにはそれほど多くはありませんが、私は 'Subject'と' IEventSource'をひとつのオブジェクトにまとめたいと思っていました。 –
Medo42