web-dev-qa-db-ja.com

Observable.FromEventではなくObservable.FromEventPatternを使用する場合

TIBCO EMSキューを呼び出すクライアントがあり、次のようにイベントを関連付けています。

_var msgConsumer = _session.CreateConsumer(responseQueue);
var response = Observable.FromEvent<EMSMessageHandler,EMSMessageEventArgs>
            (h => msgConsumer.MessageHandler += h, h => msgConsumer.MessageHandler -= h)
            .Where(arg => arg.Message.CorrelationID == message.MessageID);
_

response.Subscribe(...)を呼び出すと、System.ArgumentException "ターゲットメソッドへのバインディングエラー"が発生します。

Observable.FromEventPattern<EMSMessageEventArgs>(msgConsumer, "MessageHandler")で動作させることはできますが、イベントは文字列として取得され、それほどクリーンではありません。

また、私は_IObservable<EventPattern<EMSMessageEventArgs>>_ではなく_IObservable<EMSMessageEventArgs>_を持っています

私が理解したいのは、FromEventよりもFromEventPatternをいつ使用すればよいですか?少し試行錯誤しているようです。

56
baralong

「イベントにFromEventを使用すると、構造的に.NETイベントパターンのように見えず(つまり、送信者、イベント引数に基づいていない)、パターンベースのイベントにはFromEventPatternを使用します。」 - Bart De Smet(Rxチーム)

63

これについてもう少し詳しく説明すると、通常、監視しようとしているクラスで使用されているイベントのタイプによって、FromEventFromEventPatternのどちらを選択するかを決定できます。イベントのタイプがFromEventPatternまたは一般的なEventHandler<T>の場合は、 EventHandler を使用します。カスタムの非ジェネリックイベントハンドラータイプを使用している場合は FromEvent を使用します。次の例は Rx wiki から直接抜粋したもので、正確な例がたくさんあります 101個中 正確です。

FromEventPattern(一般的なEventHandlerを使用)

class ObserveEvent_Generic
{
    public class SomeEventArgs : EventArgs { }
    public static event EventHandler<SomeEventArgs> GenericEvent;

    static void Main()
    {
        // To consume GenericEvent as an IObservable:
        IObservable<EventPattern<SomeEventArgs>> eventAsObservable = Observable.FromEventPattern<SomeEventArgs>(
            ev => GenericEvent += ev,
            ev => GenericEvent -= ev );
    }
}

FromEvent:

class ObserveEvent_NonGeneric
{
    public class SomeEventArgs : EventArgs { }
    public delegate void SomeNonGenericEventHandler(object sender, SomeEventArgs e);
    public static event SomeNonGenericEventHandler NonGenericEvent;

    static void Main()
    {
        // To consume NonGenericEvent as an IObservable, first inspect the type of EventArgs used in the second parameter of the delegate.
        // In this case, it is SomeEventArgs.  Then, use as shown below.
        IObservable<IEvent<SomeEventArgs>> eventAsObservable = Observable.FromEvent(
            (EventHandler<SomeEventArgs> ev) => new SomeNonGenericEventHandler(ev), 
            ev => NonGenericEvent += ev,
            ev => NonGenericEvent -= ev);
    }
}
18
joelmdev

どうやら新しい構文は少し変更されています。現在の構文は次のとおりです。

// get events as observable 
var events = Observable.FromEvent<MouseButtonEventHandler, MouseEventArgs>(
    handler => MouseUp += handler, handler => MouseUp -= handler);

// subscribe to events
var subscription = events.Subscribe(args => OnMouseUp()));

// always dispose subscriptions! 
subscription.Dispose(); 
7
MovGP0