How to convert an event to IObservable if it does not match standard .NET event patterns

I have a delegate that looks like this:

public delegate void MyDelegate(int arg1, int arg2); 

And an event that looks like this:

 public event MyDelegate SomethingHappened; 

Is there an easy way to create an IObservable sequence for this event? I would like to do something like this (but it does not compile):

 var obs = Observable.FromEventPattern<int, int>(this, "SomethingHappened"); var subscription = obs.Subscribe(x,y => DoSomething(x, y)); 

....

 private void DoSomething(int value1, int value2) { ... } 
+5
source share
2 answers

There is a way to do this using Observable.FromEvent as follows.

Allows you to create the Test class to encapsulate the delegate and event definitions:

 public class Test { public delegate void MyDelegate(int arg1, int arg2); public event MyDelegate SomethingHappened; public void RaiseEvent(int a, int b) { var temp = SomethingHappened; if(temp != null) { temp(a, b); } } } 

Now, since the delegate has two arguments that are not neatly packaged in a subclass of EventArgs , we must use the conversion function to pack them into a suitable containing type. If you remember the signature of the OnNext IObservable method, it should be clear why we should do this - here we can provide only one argument.

You can create your own type for this, but I will be lazy and use Tuple<int,int> . Then we can use the Observable.FromEvent overload with the transform function as follows:

 var test = new Test(); var obs = Observable.FromEvent<Test.MyDelegate, Tuple<int,int>>( handler => (a, b) => handler(Tuple.Create(a,b)), h => test.SomethingHappened += h, h => test.SomethingHappened -= h ); 

To be clear, what we supply in this first parameter is a function that takes an OnNext handler (in this case, an Action<Tuple<int,int>> ) and returns a delegate that can be subscribed to an event (like MyDelegate ) . This delegate will be called for each event and, in turn, will call the OnNext handler passed from the Subscribe call. Thus, we get a stream of type IObservable<Tuple<int,int>> .

With on-site communication, we can subscribe like this:

 var subscription = obs.Subscribe(x => Console.WriteLine(x.Item1 + " " + x.Item2)); 

And experience with this:

 test.RaiseEvent(1, 2); 
+9
source

I haven't used Observable before, but it looks like the Observable.FromEvent method does what you want: http://msdn.microsoft.com/en-us/library/hh229271(v=vs.103).aspx

+1
source

Source: https://habr.com/ru/post/1202250/


All Articles