4

Is there an equivalent of the Task.ContinueWith operator in Rx?

I'm using Rx with Silverlight, I am making two webservice calls with the FromAsyncPattern method, and I'd like to do them synchronously.

        var o1 = Observable.FromAsyncPattern<int, string>(client.BeginGetData, client.EndGetData);
        var o2 = Observable.FromAsyncPattern<int, string>(client.BeginGetData, client.EndGetData);

Is there an operator (like Zip) that will only start / subscribe to o2 only after o1 returns Completed?
I handle failure of either web service call the same way.

foson
  • 10,037
  • 2
  • 35
  • 53

2 Answers2

7

Yes, it's called projection:

o1().SelectMany(_ => o2()).Subscribe();
Alex Zhevzhik
  • 3,347
  • 19
  • 19
  • I set breakpoints in client.BeginGetData and EndGetData and added an artifical delay in the web service. BeginGetData gets called twice before EndGetData is reached. – foson Jul 19 '11 at 20:33
  • They are coming back on separate threads so the debugger will display nondeterministic results, this is indeed the correct answer – Ana Betts Jul 19 '11 at 21:17
  • @foson, you should set breakpoint inside SelectMany and check that EndGetData for first operation is already called. – Alex Zhevzhik Jul 20 '11 at 04:49
  • My mistake was that I was passing the arguments to the Func returned by Observable.FromAsyncPattern before my select statement and selecting the resulting IObservable. I see now you must only pass the argument within the SelectMany. Thanks! – foson Jul 20 '11 at 13:52
6

While Alex is right, the other way you can do this is:

Observable.Concat(
    o1(4),
    o2(6))
  .Subscribe(x => /* Always one, then two */);

Which guarantees that o2 only runs after o1 - as opposed to Merge, which would run them at the same time:

Observable.Merge(
    o1(4),
    o2(6))
  .Subscribe(x => /* Either one or two */);
Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • 1
    If you don't need to combine the result from operation A with operation B somehow, I prefer .Concat. I think it's semantically more clear. If you need to combine observable results (like passing the result from A into the call that results in B), then projection is the way to go. – Anderson Imes Jul 19 '11 at 21:52
  • Thanks for the suggestion. I agree that Concat is clearer, but I'll probably go with select/SelectMany in my real world usage since my webservices will be returning different types and with SelectMany I can process both returned values in one call of my onNext handler. – foson Jul 20 '11 at 13:56