Rx中是否有类似于Task.ContinueWith操作符的等效操作符?

4

在Rx中是否有类似于Task.ContinueWith操作符的等效操作符?

我正在使用Rx和Silverlight,使用FromAsyncPattern方法进行两个webservice调用,并且我想要以同步的方式执行它们。

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

是否有一个操作符(类似于Zip),只有在o1返回Completed后才会开始/订阅o2?
我以相同的方式处理任何Web服务调用的失败。

2个回答

7

是的,这被称为投射:

o1().SelectMany(_ => o2()).Subscribe();

我在client.BeginGetData和EndGetData中设置了断点,并在Web服务中添加了人为延迟。在到达EndGetData之前,BeginGetData会被调用两次。 - foson
它们将在不同的线程上返回,因此调试器将显示不确定的结果,这确实是正确的答案。 - Ana Betts
@foson,你应该在SelectMany内设置断点,并检查第一个操作的EndGetData是否已经被调用。 - Alex Zhevzhik
我的错误在于我将参数传递给了由Observable.FromAsyncPattern返回的Func,而不是在选择语句中选择结果IObservable之前。现在我明白了,你必须只在SelectMany中传递参数。谢谢! - foson

6
虽然Alex是正确的,但你也可以通过以下方式实现:

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

保证o2在o1之后运行——与Merge相反,Merge会同时运行它们。
Observable.Merge(
    o1(4),
    o2(6))
  .Subscribe(x => /* Either one or two */);

1
如果您不需要以某种方式将操作A的结果与操作B的结果合并,我更喜欢使用.Concat。我认为这在语义上更清晰。如果您需要组合可观察到的结果(例如将A的结果传递到导致B的调用中),那么投影是正确的选择。 - Anderson Imes
谢谢您的建议。我同意Concat更清晰,但在实际使用中,我可能会选择select/SelectMany,因为我的Web服务将返回不同类型的值,并且使用SelectMany可以在一个onNext处理程序调用中处理两个返回值。 - foson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接