I have a third party API that I do not have the source to. I instantiate a callback to an event like this:
using namespace API; // This is where APIClient lives
namespace TestApiClientUI
{
public partial class Form1 : Form
{
APIClient apiClient = new APICLient();
apiClient.QuoteUpdated += api_ClientUpdated;
private void api_ClientUpdated(object sender, string s, double b, double a)
{
}
}
}
How do I wrap this into an Rx Observable.FromEvent?
Also, is there a way to do it so the overhead of the wraps copy are as little (zero-copy) as possible?
Let's define a struct to store the event args.
Now we can define an
IObservable<QuoteUpdate>as follows.The first lambda defines a mapping from
Action<QuoteUpdate>toApiQuoteHandler. The action, calledemit, is what actually broadcasts a value to the subscribers of the observable we are defining. Think of callingemit(value);as something likeforeach (var subscriber in subscribers) { subscriber.OnNext(value); }.The reason we need this first mapping is because the actual underlying event only knows how to subscribe and unsubscribe
ApiQuoteHandlerinstances. The second and third lambdas are of typeAction<ApiQuoteHandler. They are called on subscription and unsubscription, respectively.When an
IObserver<QuoteUpdate> observersubscribes to theIObservable<QuoteUpdate>we have defined, this is what happens:observer.OnNext(of typeAction<QuoteUpdate>) is passed into our first lambda as the variableemit. This creates anApiQuoteHandlerthat wraps theobserver.ApiQuoteHandleris then passed into our second lambda as the variablehandler. Thehandlersubscribes to theQuoteUpdatedevent on yourapiClient.IDisposablereturned fromSubscribemethod on ourIObservable<QuoteUpdate>contains a reference to theApiQuoteHandlerthat was created by the first of our three lambdas.IDisposableis disposed, the third lambda is called with the sameApiQuoteHandlerfrom before, unsubscribing from the underlying event.Because you need a single
IObservable<T>for someTyet you have event args(s, b, a), you must define some struct or class to store the three values. I would not worry about the cost of copying astringreference and twodoublevalues.