Why/How should I use Publish without Connect?

China☆狼群 提交于 2019-12-11 07:19:30

问题


Why/how should I use .Publish() without a Connect or RefCount call following? What does it do? Example code:

var source = new Subject<int>();

var pairs = source.Publish(_source => _source
    .Skip(1)
    .Zip(_source, (newer, older) => (older, newer))
);

pairs.Subscribe(p => Console.WriteLine(p));

source.OnNext(1);
source.OnNext(2);
source.OnNext(3);
source.OnNext(4);

How is pairs different from pairs2 here:

var pairs2 = source
    .Skip(1)
    .Zip(source, (newer, older) => (older, newer));

回答1:


The Publish<TSource, TResult>(Func<IObservable<TSource, IObservable<TResult>> selector) overload is poorly documented. Lee Campbell doesn't cover it in introtorx.com. It doesn't return an IConnectableObservable, which is what most people associate with Publish, and therefore doesn't require or support a Connect or RefCount call.

This form of Publish is basically a form of defensive coding, against possible side-effects in a source observable. It subscribes once to the source, then can safely 'multicast' all messages via the passed in parameter. If you look at the question code, there's only once mention of source, and two mentions of _source. _source here is the safely multicasted observable, source is the unsafe one.

In the above example, the source is a simple Subject, so it's not really unsafe, and therefore Publish has no effect. However, if you were to replace source with this:

var source = Observable.Create<int>(o =>
{
    Console.WriteLine("Print me once");
    o.OnNext(1);
    o.OnNext(2);
    o.OnNext(3);
    o.OnNext(4);
    return System.Reactive.Disposables.Disposable.Empty;
});

...you would find "Print me once" printed once with pairs (correct), and twice with pairs2. This effect has similar implications where your observable wraps things like DB queries, web requests, network calls, file reads, and other side-effecting code that you want to happen only once and not multiple times.

TL;DR: If you have an observable query that references an observable twice, it is best to wrap that observable in a Publish call.



来源:https://stackoverflow.com/questions/53747350/why-how-should-i-use-publish-without-connect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!