我有一些代码,我期望以某种方式工作,但事实并非如此,我想知道我做错了什么:
class Program
{
static void Main(string[] args)
{
var ints = Observable.Interval(TimeSpan.FromMilliseconds(1000));
var windowed = ints.Window(() => ints.Select(i => i / 3).DistinctUntilChanged());
windowed.Subscribe(HandleNewWindow);
Console.ReadLine();
}
public static void HandleNewWindow(IObservable<long> ints)
{
Console.WriteLine("New sequence received");
ints.Subscribe(Console.WriteLine);
}
}
此输出应为:
收到新序列
0
1
2
收到新序列
3
4
5
收到新序列
6
7
8
...
但它是:
收到新序列
0
收到新序列
1
收到新序列
2
收到新序列
3
收到新序列
4
收到新序列
5
收到新序列
6
...
请注意,如果我使用不同的行来定义我的窗口,例如:
var windowed = ints.Window(() => Observable.Interval(TimeSpan.FromMilliseconds(3000)));
然后一切正常。
Window是否存在使用从Observable派生的窗口关闭的问题,或者我是否遗漏了重要的东西?
答案 0 :(得分:1)
您需要使用Publish
运算符来创建可以共享源的订阅的可观察对象。看起来每次关闭窗口时,它都会在内部设置对源的新订阅。使用发布可确保您不会每次都开始新的间隔
您还需要将窗口关闭选择器更改为仅在您希望关闭窗口时触发。
class Program
{
static void Main(string[] args)
{
var ints = Observable.Interval(TimeSpan.FromMilliseconds(1000))
.Publish(new Subject<long>());
var closeOnValues = ints.Where(ShouldClose);
var windowed = ints.Window(() => closeOnValues);
windowed.Subscribe(HandleNewWindow);
Console.ReadLine();
}
public static void HandleNewWindow(IObservable<long> ints)
{
Console.WriteLine("New sequence received");
ints.Subscribe(Console.WriteLine);
}
public static bool ShouldClose(long index)
{
var notZero = index != 0;
var countIsMultipleOfThree = (index + 1) % 3 == 0;
return notZero && countIsMultipleOfThree;
}
}
答案 1 :(得分:0)
我有一些看起来更像我的原始代码并产生预期值的东西。 我仍然不明白为什么这个代码有效而不是另一个代码,但我认为詹姆斯·海伊在他说某种重新订阅发生在幕后的时候会把它钉住。
class Program
{
static void Main(string[] args)
{
var ints = Observable.Interval(TimeSpan.FromMilliseconds(1000));
var windowClosings = ints
.Select(i => i / 3)
.DistinctUntilChanged()
.SkipWhile((i) => i == 0)
.Publish(new Subject<long>());
var windowed = ints.Window(() => windowClosings);
windowed.Subscribe(HandleNewWindow);
Console.ReadLine();
}
public static void HandleNewWindow(IObservable<long> ints)
{
Console.WriteLine("New sequence received");
ints.Subscribe(Console.WriteLine);
}
}
除了仅删除第一个windowClosing的SkipWhile之外,这里的主要区别在于我必须发布windowClosings(而不是原始的Observable)。
仍然不能100%确定为什么我必须这样做。