其他分享
首页 > 其他分享> > 为什么每个订阅都完全解析IObservable链?

为什么每个订阅都完全解析IObservable链?

作者:互联网

我有一个问题,如何解决IObervable链.
我认为,如果多个观察者订阅同一个IObservable,则只有在流发出新项目时,整个链才会解析一次.

相反,似乎每个订阅都运行整个链.

如果我的整个程序逻辑是使用IObservables并将它们链接在一起构成的,那么在我看来,代码正在不必要地运行具有相同结果的相同方法.

>这是故意行为吗?又为什么呢?
>如果可以,可以避免吗?还是一个坏主意?

下面的代码是用LINQPad编写的:

{
    var subject = Observable.Range(1, 1);

    var observable1 = subject
        .Select(value =>
        {
            var nextValue = value + 2;
            Console.Write("\n Result of expensive computation: " + nextValue);
            return nextValue;
        });

    var observable2 = observable1
        .Select(value =>
        {
            var nextValue = 2 * value;
            Console.Write("\n Result of another expensive computation: " + nextValue);
            return nextValue;
        });

    observable2.Subscribe(_ => Console.Write("\n Data received on first subscription."));

    observable2.Subscribe(_ => Console.Write("\n Data received on second subscription."));
}

结果:

Result of expensive computation: 3

Result of another expensive computation: 6

Data received on first subscription.

Result of expensive computation: 3

Result of another expensive computation: 6

Data received on second subscription.

但是我期望:

Result of expensive computation: 3

Result of another expensive computation: 6

Data received on first subscription.

Data received on second subscription.

感谢您的任何答案.

干杯,

解决方法:

首先回答您的问题:

>是的,这是预期的行为.
>是的,可以避免.
>回避不是一个坏主意.

正如@supertopi所说,您创建了一个冷的可观察对象,其功能与您概述的一样.将其变成一个热门观察者,您将拥有所需的功能.

您可以按照以下方式进行操作:

{
    var subject = Observable.Range(1, 1);

    var observable1 = subject
        .Select(value =>
        {
            var nextValue = value + 2;
            Console.Write("\n Result of expensive computation: " + nextValue);
            return nextValue;
        });

    var observable2 = observable1
        .Select(value =>
        {
            var nextValue = 2 * value;
            Console.Write("\n Result of another expensive computation: " + nextValue);
            return nextValue;
        });

    var hotObservable = observable2.Publish().RefCount();

    hotObservable.Subscribe(_ => Console.Write("\n Data received on first subscription."));

    hotObservable.Subscribe(_ => Console.Write("\n Data received on second subscription."));

}

冷观测值:

>多个订阅触发链式操作的多个代码重新运行
>通常来自Observable.Create / Range / Generate / Interval / Timer
>就像可枚举的项目,其中明确定义了项目之间的时间间隔.

热点可观察物:

>多个订阅通常共享链式操作的结果
>通常来自事件,可观察到的冷战事件或主题
>就像您可以处理的一系列事件一样;无论您是否喜欢,它们都会发生.

我认为,最好的区别是源是否在没有订阅的情况下“运行”.例如,无论是否订阅了按钮,单击事件仍然会发生.相反,如果没有订阅,Observable.Timer将不执行任何操作.

至于为什么…我不能代表Rx设计师.冷观测和热观测是混乱/错误的常见原因.我认为更好地明确他们的立场可能会改善这种情况.话虽如此,我不确定那是过去还是现在.

标签:system-reactive,c
来源: https://codeday.me/bug/20191118/2024898.html