4

我有一个带有以下标头的数据源:

IObservable<IObservable<object>> MagicSource(IObservable<string> strings)

我将字符串推到那里,它给了我结果,但考虑到我只需要最后一个字符串的答案,我使用 Switch 语句来取消以前的:

MagicSource(StringsProvider).Switch().Subscribe(r => {/*...*/});

这很好用,但我还需要收到通知,即当前正在处理的字符串已更改,以准备我的结果视图。如何获得此类通知?

4

4 回答 4

1

实际上最好的方法是以下。您需要使用多播。

// Ensure that you are using multicast
var source = MagicSource(strings).Publish().RefCount();

// Subscribe to this for notification and count
var notifications = source.Select((v,i)=>i);

// Subscribe to this to get flattened data
var flattened = source.Switch()

这样做Publish().RefCount()会创建一个多播源,该多播源在进行第一个订阅时订阅一次,然后在删除最后一个订阅时取消订阅。要记住的重要一点是,只对源进行一次订阅,这可能很重要,也可能不重要。

于 2013-08-19T09:25:54.360 回答
1

我个人会避免使用 Do 语句。

您可能会创建一个投影。

在这个投影中,我假设您想要对当前内部序列的处置采取行动(也许从表中清除当前记录?)

MagicSource(StringsProvider)
    .Select(inner=>inner.Finally(CleanUp))
    .Switch()
    .Subscribe(r => {/*...*/});

如果您想做同样的事情,但针对内部序列的订阅(而不是处置),那么您还有更多工作要做。我将创建对称运算符到最后,Initially(Action)

public static class ObservableEx
{
    public static IObservable<T> Initially<T>(this IObservable<T> source, Action onSubscribe)
    {
        return Observable.Create<T>(o=>{
            try
            {           
                onSubscribe();
                return source.Subscribe(o);
            }
            catch (Exception ex)
            {
                o.OnError(ex);
                return Disposable.Empty;
            }
        });
    }
}

然后你可以像这样使用它

MagicSource(StringsProvider)
    .Select(inner=>inner.Initially(Prepare))
    .Switch()
    .Subscribe(r => {/*...*/});
于 2013-08-19T10:56:44.270 回答
1

您应该为每个元素添加一个索引,指示它来自的子源。做起来很简单。

IObservable<Tuple<string, int>> results =
 MagicSource(StringsProvider)
 .Select((v,i)=>v.Select(y=>Tuple.Create(y,i))
 .Switch()
于 2013-08-19T05:15:30.647 回答
1

最简单的方法是只使用一个Do语句:

这里有一些品种。

如果您对工作原理一无所知MagicSource并且无法将新传入的字符串与新的内部流准确关联:

Action NewStreamProduced = ...;
MagicSource(StringsProvider).Do(_ => NewStreamProduced).Switch()....

如果您确实知道MagicSource每次新字符串到达​​时都会同步生成一个新的内部流,那么您可以Do在调用之前放置MagicSource

Action<string> NewStringArrivedWhichMeansWeAreSwitching = ...;
MagicSource(StringsProvider.Do(NewStringArrivedWhichMeansWeAreSwitching)).Switch()...
于 2013-08-17T21:59:55.387 回答