PL's answer , if it suits your specification perfectly, but I thought you could get better results without fighting RX with .First (), but hugging it with creating an observable for your component:
public static IObservable<Unit> AsObservable(this Component component) { return Observable.Defer(() => { component.BeginStart(); return Observable .FromEvent<EventArgs>(component, "Started") .Select(_ => new Unit()); }); }
Then you can use it as a lock:
new Component().AsObservable().First();
Non-blocking:
new Component().AsObservable().Subscribe(_ => Console.WriteLine("Done"));
Hot:
var pub = new Component().AsObservable().Publish(); pub.Subscribe(_ => Console.WriteLine("Sub1")); pub.Subscribe(_ => Console.WriteLine("Sub2")); pub.Connect();
typesetting:
new Component().AsObservable().Delay(TimeSpan.FromSeconds(1));
etc...
EDIT: for the case of several events that you need to wait and collect information, you can use the following option:
public static IObservable<EventArgs> AsObservable(this Component component) { return Observable.Defer(() => { component.BeginStart(); return Observable.FromEvent<EventArgs>(component, "Started1").Take(1) .Merge( Observable.FromEvent<EventArgs>(component, "Started2").Take(1)) .Select(evt => evt.EventArgs); }); }
However, if you want to block until completion, you can use .AsObservable.Last() .
Sergey Aldoukhov
source share