В настоящее время у меня есть функция, позволяющая пользователям Timer()
запускать наблюдаемое немедленно, а затем каждые 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()
, чтобы сгенерировать экспоненциально более низкие значения для задержки, но не смог заставить его работать. Я был на правильном пути? Есть ли лучшие способы сделать что-то подобное?
Пересмотрен код с ответом от Шломо:
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)));
Закончено изменение условного выражения, чтобы первый элемент был немедленным.