Matthew's answer is close but has some problems. First, it is eager, which is not normally in the spirit of Rx/Functional programming. Next I think that you will want to be able to release the event handles when the consumer disposes. Finally the usage of a subject should be a code smell, and this case it points to the two problems above :-)
Here I use Observable.Create (which should be your #1 goto tool in the tool box, with subjects being your last resort) to lazily connect, and also offer disconnection/releasing events when the subscription is disposed.
private IObservable<string> GetStrings()
{
return Observable.Create<string>(o=>
{
SomeDataObject.ReadyEventHandler ReadyHandler = null;
SomeDataObject.ErrorEventHandler ErrorHandler = null;
ReadyHandler += () =>
{
for (int i =0; i < dataObject.ItemCount; i++)
o.OnNext(dataObject[i].ToString());
o.OnCompleted();
}
ErrorHandler += () =>
{
o.OnError(new Exception("oops!"));
}
dataObject.Ready += ReadyHandler;
dataObject.Error += ErrorHandler;
dataObject.DoRequest();
return Disposable.Create(()=>
{
dataObject.Ready -= ReadyHandler;
dataObject.Error -= ErrorHandler;
});
}
}
I would also consider moving dataObject
to a parameter to the method too. Sharing state in an Async system is a source of problems.