C# 为什么每次订阅都会完全解析IObservable链?
我有一个问题是如何解决爱宝宝链的问题。 我认为,如果多个观察者订阅同一个IObservable,那么如果流发出一个新项,整个链将只解析一次 相反,似乎每个订阅都会运行整个链 如果我的整个程序逻辑都是使用IObservables并将它们链接在一起,那么在我看来,代码运行的方法是相同的,结果也是相同的C# 为什么每次订阅都会完全解析IObservable链?,c#,system.reactive,C#,System.reactive,我有一个问题是如何解决爱宝宝链的问题。 我认为,如果多个观察者订阅同一个IObservable,那么如果流发出一个新项,整个链将只解析一次 相反,似乎每个订阅都会运行整个链 如果我的整个程序逻辑都是使用IObservables并将它们链接在一起,那么在我看来,代码运行的方法是相同的,结果也是相同的 这是故意的行为吗?为什么 如果是,可以避免吗?或者这是个坏主意 下面的代码是用LINQPad编写的: { var subject = Observable.Range(1, 1);
- 这是故意的行为吗?为什么
- 如果是,可以避免吗?或者这是个坏主意
{
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."));
}
结果:
计算结果:3
另一个昂贵计算的结果:6
第一次订阅时收到的数据
计算结果:3
另一个昂贵计算的结果:6
第二次订阅时收到的数据
然而,我期望:
计算结果:3
另一个昂贵计算的结果:6
第一次订阅时收到的数据
第二次订阅时收到的数据
谢谢你的回答
干杯,
Rob首先回答您的问题:
- 是的,这是故意的行为李>
- 是的,这是可以避免的李>
- 回避不是个坏主意
{
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.Timer
在没有订阅的情况下不会执行任何操作
至于为什么。。。我不能代表Rx设计师说话。冷态与热态的观测值经常引起混淆/错误。我认为,在他们周围有一个更好的明确性可以改善这种情况。话虽如此,我不确定这是怎么做到的。这是冷观测的预期行为,可以通过使观测变热来避免。我建议你在Lee Campbell关于Rx的介绍中读一下冷热观测。或者通过SO文档,谢谢,这让我走上了正确的轨道。我真的应该再读几遍那个网站。谢谢。因此.Publish().RefCount()通常用于使冷的可观察到的热。但是,在代码修复中,第二个订阅服务器从不触发。第一个订户让可观察对象运行其创建函数,并在第二个订户可以订阅之前结束它,对吗?正确。因为在任何可观察对象中都没有异步性,所以所有东西都是同步运行的。即使您将源代码增加到
var subject=Observable.Range(100000000)代码>或其他一些大数字,第二个不会发射。所有一百万个数字都将在第一个订阅上同步运行。如果要使用异步值对其进行测试,请使用var subject=Observable.Timer(TimeSpan.frommissions(10))。选择(=>1)代码>。这将导致两个订阅都被取消。