gpt4 book ai didi

c# - 如何随时间动态延迟可观察的

转载 作者:行者123 更新时间:2023-11-30 22:58:26 25 4
gpt4 key购买 nike

我目前有一个功能,用户 Timer() 可以立即触发一个 observable,然后每隔 x 毫秒触发一次。

HoldPayloads = Observable.Merge(
EnumeratedSymbolKeys.Select(
o => Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => o.PreviewMouseLeftButtonDown += h,
h => o.PreviewMouseLeftButtonDown -= h)
.Select(_ => Observable.Timer(DateTimeOffset.Now, TimeSpan.FromMilliseconds(o.Frequency))
.TakeUntil(Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => o.PreviewMouseLeftButtonUp += h,
h => o.PreviewMouseLeftButtonUp -= h)))
.Switch()
.Select(_ => o.Payload)));

我想要的是单击按钮时可观察到的立即触发,然后在初始较长的延迟后开始以更快的间隔或减少的间隔重复到极限,如下所示:

--x------x--x--x--x--x--x-->

--x------x----x---x--x-x-x->

我尝试将 Delay()Scan() 结合使用以生成指数级较低的延迟值,但无法使其正常工作。我走在正确的轨道上吗?有没有更好的方法来做这样的事情?

使用 Shlomo 的答案修改代码:

HoldPayloads = Observable.Merge(
EnumeratedSymbolKeys.Select(
o => Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => o.PreviewMouseLeftButtonDown += h,
h => o.PreviewMouseLeftButtonDown -= h)
.Select(_ => Observable.Generate(
1,
q => true,
i => i+1,
i => i,
i => i==1
? TimeSpan.FromMilliseconds(0)
: i > 10
? TimeSpan.FromMilliseconds(50)
: TimeSpan.FromMilliseconds(500/i))
.TakeUntil(Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => o.PreviewMouseLeftButtonUp += h,
h => o.PreviewMouseLeftButtonUp -= h)))
.Switch()
.Select(_ => o.Payload)));

最后修改了条件,以便第一个项目是立即的。

最佳答案

Observable.Generate 是你的 friend (在 this 页面上讨论得很好)。

对于越来越频繁的值,将 .Select(_ => Observable.Timer(DateTimeOffset.Now, TimeSpan.FromMilliseconds(o.Frequency)) 替换为如下内容:

Observable.Generate(
1,
_ => true,
i => i + 1,
i => i,
i => i > 10
? TimeSpan.FromMilliseconds(50)
: TimeSpan.FromMilliseconds(500 / i)
)

无论您的模式是什么,请将其融入最后一个参数。将 Generate 想象成一个响应式(Reactive) for 循环,其中包含所有可用的拨号盘。


编辑:

使用上面的代码,Generate 中的第一项将被延迟。如果你想要第一个项目立即,然后第二个项目延迟,你可以这样做:

Observable.Generate(
1,
_ => true,
i => i + 1,
i => i,
i => i > 10
? TimeSpan.FromMilliseconds(50)
: TimeSpan.FromMilliseconds(500 / i)
)
.StartWith(0)

原来的 .Select(_ => Observable.Timer(DateTimeOffset.Now, TimeSpan.FromMilliseconds(o.Frequency) 现在是 .Select(_ => Observable.Generate( ...).StartWith(0))

关于c# - 如何随时间动态延迟可观察的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53009121/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com