C# 触发第一个事件后数秒的RX缓冲区事件
我有一个filewatcher,可以从中观察创建和更改的事件。 我希望在触发(创建或更改)第一个事件时,它需要开始缓冲10秒,在这10秒之后,我希望处理缓冲的事件 我已经得到的是:C# 触发第一个事件后数秒的RX缓冲区事件,c#,system.reactive,C#,System.reactive,我有一个filewatcher,可以从中观察创建和更改的事件。 我希望在触发(创建或更改)第一个事件时,它需要开始缓冲10秒,在这10秒之后,我希望处理缓冲的事件 我已经得到的是: Observable.FromEventPattern<FileSystemEventArgs>(FileSystemWatcher, "Created") .Merge(Observable.FromEventPattern<FileSystemEventArgs&
Observable.FromEventPattern<FileSystemEventArgs>(FileSystemWatcher, "Created")
.Merge(Observable.FromEventPattern<FileSystemEventArgs>(FileSystemWatcher, "Changed"))
.Buffer(TimeSpan.FromSeconds(10))
.Subscribe(list =>
{
Debug.WriteLine("Do something");
});
Observable.FromEventPattern(FileSystemWatcher,“已创建”)
.Merge(可观察的.FromEventPattern(FileSystemWatcher,“已更改”))
.缓冲区(时间跨度从秒(10))
.订阅(列表=>
{
Debug.WriteLine(“做某事”);
});
此代码执行“Debug.WriteLine(“Do something”);”每10秒
编辑:
好吧,让我试着用时间线来解释一下
希望这能让事情变得清楚我假设您想要以下行为:
timeline: 0--1--2--3--4--5--6--7--8--9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27
events : x--x--x--x--x-------------------------------------x--x--x--x--x------------------
stdbuff : |----------------------------|-----------------------------|---------------------
desired : BeginCapture-----------------Return---------------BeginCapture------------------Return
var primaryEvents = initialSource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged();
使用直接Buffer
的问题在于,它看起来像上面标注的stdbuff
,并将第二组事件分成两组,从而为第二组事件生成两个列表:一个包含三个事件,一个包含两个事件。您需要一个列表(用于第二个组),使用类似于所需
流的逻辑。从0开始捕获,从10返回列表。17点开始抓拍,27点返回列表
如果我(再次)误解了你,请张贴一个大理石图,类似于上面,代表你希望事情如何运作
假设我理解正确,下面的代码将工作
//var initialSource = Observable.FromEventPattern<FileSystemEventArgs>(fileWatcher, nameof(FileSystemWatcher.Created))
// .Merge(Observable.FromEventPattern<FileSystemEventArgs>(fileWatcher, nameof(FileSystemWatcher.Changed)));
//Comment this out, and use the above lines for your code. This just makes testing the Rx components much easier.
var initialSource = Observable.Interval(TimeSpan.FromSeconds(1)).Take(5)
.Concat(Observable.Empty<long>().Delay(TimeSpan.FromSeconds(13)))
.Concat(Observable.Interval(TimeSpan.FromSeconds(1)).Take(5));
initialSource
.Publish( _source => _source
.Buffer(_source
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10))
)
)
.Subscribe(list =>
{
Debug.WriteLine($"Time-stamp: {DateTime.Now.ToLongTimeString()}");
Debug.WriteLine($"List Count: {list.Count}");
});
一旦我们有了可以表示窗口打开的BeginCapture
事件,就很容易找到Return
事件或窗口关闭:
var closeEvents = primaryEvents.Delay(TimeSpan.FromSeconds(10));
实际上,由于我们关心的收盘和开盘之间没有发生任何事情,因此我们只需要担心收盘事件,因此我们可以将其缩小为:
var closeEvents = initialSource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10));
将其插入Buffer
,其中closeEvents
为bufferbounders
:
var bufferredLists = initialSource
.Buffer(initialsource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10))
);
最后,由于我们有多个对
initialSource
的订阅,我们希望使用Publish
来确保并发正常工作,从而得到最终答案。我假设您需要以下行为:
timeline: 0--1--2--3--4--5--6--7--8--9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27
events : x--x--x--x--x-------------------------------------x--x--x--x--x------------------
stdbuff : |----------------------------|-----------------------------|---------------------
desired : BeginCapture-----------------Return---------------BeginCapture------------------Return
var primaryEvents = initialSource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged();
使用直接Buffer
的问题在于,它看起来像上面标注的stdbuff
,并将第二组事件分成两组,从而为第二组事件生成两个列表:一个包含三个事件,一个包含两个事件。您需要一个列表(用于第二个组),使用类似于所需
流的逻辑。从0开始捕获,从10返回列表。17点开始抓拍,27点返回列表
如果我(再次)误解了你,请张贴一个大理石图,类似于上面,代表你希望事情如何运作
假设我理解正确,下面的代码将工作
//var initialSource = Observable.FromEventPattern<FileSystemEventArgs>(fileWatcher, nameof(FileSystemWatcher.Created))
// .Merge(Observable.FromEventPattern<FileSystemEventArgs>(fileWatcher, nameof(FileSystemWatcher.Changed)));
//Comment this out, and use the above lines for your code. This just makes testing the Rx components much easier.
var initialSource = Observable.Interval(TimeSpan.FromSeconds(1)).Take(5)
.Concat(Observable.Empty<long>().Delay(TimeSpan.FromSeconds(13)))
.Concat(Observable.Interval(TimeSpan.FromSeconds(1)).Take(5));
initialSource
.Publish( _source => _source
.Buffer(_source
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10))
)
)
.Subscribe(list =>
{
Debug.WriteLine($"Time-stamp: {DateTime.Now.ToLongTimeString()}");
Debug.WriteLine($"List Count: {list.Count}");
});
一旦我们有了可以表示窗口打开的BeginCapture
事件,就很容易找到Return
事件或窗口关闭:
var closeEvents = primaryEvents.Delay(TimeSpan.FromSeconds(10));
实际上,由于我们关心的收盘和开盘之间没有发生任何事情,因此我们只需要担心收盘事件,因此我们可以将其缩小为:
var closeEvents = initialSource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10));
将其插入Buffer
,其中closeEvents
为bufferbounders
:
var bufferredLists = initialSource
.Buffer(initialsource
.Scan(DateTimeOffset.MinValue, (lastPrimary, _) => DateTimeOffset.Now - lastPrimary > TimeSpan.FromSeconds(10) ? DateTimeOffset.Now : lastPrimary)
.DistinctUntilChanged()
.Delay(TimeSpan.FromSeconds(10))
);
最后,由于我们有多个订阅
initialSource
,我们希望使用Publish
来确保并发正常工作,从而得出最终答案。您当前的代码有什么问题?您为什么不使用列表
?或者你想单独处理列表中的每一项?你只想触发一次还是什么?听起来你的解决方案是合适的。附带说明:你应该保留一个订阅的引用,当你对这些事件不再感兴趣时将其处理掉。如果您不处置订阅并且它超出范围,那么它可能仍然保留对事件的强引用(并可能导致泄漏)。请相应地编辑答案。您当前的代码有什么问题?您为什么不使用列表
?或者你想单独处理列表中的每一项?你只想触发一次还是什么?听起来你的解决方案是合适的。附带说明:你应该保留一个订阅的引用,当你对这些事件不再感兴趣时将其处理掉。如果您不处理订阅并且它超出了范围,那么它可能仍然保留对事件的强引用(并可能导致泄漏)。相应地编辑了答案。请为您期望它如何工作写一个时间表。这确实有效。我想会有一个更简单的解决办法。有点