How to properly observe non-standard events?

后端 未结 1 1757
北海茫月
北海茫月 2021-01-14 09:07

I am new to Reactive Extensions, and dealing with a COM Library that has events defined like this:

public delegate void MyDelegate(int requestId, double pric         


        
相关标签:
1条回答
  • 2021-01-14 09:56

    There is a special overload of FromEvent for it. It is a little goofy to get your head around but the function signature looks like:

    IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Func<Action<TEventArgs>, TDelegate> conversion, 
                                                             Action<TDelegate> addHandler, 
                                                             Action<TDelegate> removeHandler);
    

    The conversion function is the important part here, basically you are telling Rx how your delegate maps to a concrete type.

    In your scenario it ends up looking something like this:

    Observable.FromEvent<MyDelegate, MyArgs>(
      converter => new MyDelegate(
                      (id, price, amount) => converter(new MyArgs { 
                                                            RequestId = id, 
                                                            Price = price, 
                                                            Amount = amount
                                                           })
                   ),
      handler => MyEvent += handler,
      handler => MyEvent -= handler);
    

    So what is all this doing? Internally, it is similar to what you are doing (I'll paraphrase what it does conceptually, since the implementation is slightly more complicated). When a new subscription is made, the conversion function will be invoked with observer.OnNext passed in as the converter argument. This lambda will return a new MyDelegate instance that wraps the conversion function that we provided ((id, price, amount) => ...). This is what is then passed to the handler => MyEvent += handler method.

    After that each time the event is fired it will call our lambda method and convert the passed arguments into an instance of MyArgs which is then delivered to converter/observer.OnNext.

    In addition, to all that magic it will also take care of cleaning up the event handlers when you are done with it, gracefully hand exceptions down stream and will manage the memory over head by sharing a single event handler across multiple observers.

    Source code

    0 讨论(0)
提交回复
热议问题