score:2

Accepted answer

Try this:

public static IObservable<List<string>> GetUrlList(Uri url)
{
    var result = (
        from request in Observable.Return(
            GetWebRequest(url, false))
        from response in Observable.FromAsyncPattern<WebResponse>(
            request.BeginGetResponse, request.EndGetResponse)()
        from item in GetUrlCollection(response)
            .ToObservable()
            .ToArray()
        select item
            .ToList());
    return result;
}

My only concern with this whole approach is that your GetUrlCollection(response) is returning an enumerable. You really should code this to return an observable.

score:1

Hmmm I think Observable.Start is your friend here. You have a bunch of code that it looks like you are forcing into Observable Sequences, when they really don't look like they are.

Remember Rx is designed to work with sequences of push data. You seem to have a sequence of 1 that happens to be a List. TPL/Task/async would be a good fit here.

If you do want to use Rx, I would suggest avoiding boucing around between IEnumable and IObservable. Doing so is a quick way to creating nasty race conditions and confusing the next developer.

public static IObservable<List<string>> GetUrlList(Uri url) 
{
  return Observable.Start(()=>
  {
    var request = GetWebRequest(url, false);
    return GetUrlCollection(request);//Code change here??
  });
}

Here you can happily be synchronous in your Observable.Start delegate. This should be a lot easier for the next guy to understand (i.e. this is a single value sequence with the UrlCollection as the value).


Related Articles