为什么每个订阅都完全解析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