我有一个事件源source
,它会在短时间内产生几个事件,然后保持沉默。我几乎写了自己的实现Window
,在文档中找到了实现,但偶然发现了死锁。
这是我尝试转换IObservable<T>
的方式IObservable<IList<T>
(将我在此期间收到的所有事件都окна
放入列表中):
source.Window(TimeSpan.FromSeconds(1)).Select(obs => obs.ToListObservable())
按照设计,它应该阻止结果事件的输出直到结束окна
,但它只是死锁。
告诉我如何在不手动处理内部回调的情况下实现这一点IObservable
UPD:
我想将 2 个事件分层到一个窗口中。这样第一个事件开始窗口的倒计时,然后窗口本身通过 TimeSpan 关闭。用代码测试:
var source = Observable
.Interval(TimeSpan.FromMilliseconds(300));
var output = source.Window(TimeSpan.FromMilliseconds(700)).SelectMany(window => window.ToList());
using var subscription = output
.Subscribe(list => Console.WriteLine(">>" + string.Join("; ", list)));
Console.ReadLine();
UPD2:
我仍在尝试将“窗口”设置为像“开关”一样工作:打开它 - 它开始录制,关闭它 - 它结束录制并且可以打开它。
var state = false;
var output = source.Delay(TimeSpan.FromMilliseconds(50))
.Window(source.Where(next => state == false).Select(next=>
{
state = true;
return DateTime.UtcNow + TimeSpan.FromMilliseconds(610);
}), time => source.Where(next =>
{
var shellEnd = time < DateTime.UtcNow;
if (shellEnd)
{
state = false;
}
return shellEnd;
}))
.SelectMany(window => window.ToList());
这里仍然存在问题:
- 有时列表中有三个事件而不是两个
- 延迟
Delay
往往无济于事。它应该稍微延迟事件调用,以便在事件传播之前打开/关闭窗口