问题描述
具体我试图模拟执行一个动作,如果键被按下的持续时间大于阈值(T)。
我试图做到这一点使用无功扩展.NET(稳定的1.0版本)的无状态变量。
下面是我输入的大理石图,我所需要的:
让T = 3(SO 4 DDDD没有钥匙了事件一补键按住)
的keyDown:--dddd --- DD - D-DDDDDDDDDD ----
KEYUP:-----------ü-----ü - U ---------------ü -
期望:--------一---------------一----------
下面是一些例子code我想出了工作,但使用的状态变量。
VAR keyDownStream = Observable.FromEventPattern< KeyEventArgs>(这一点,的KeyDown),其中(参数=> args.EventArgs.Key == Key.OemPeriod)。
VAR keyUpStream = Observable.FromEventPattern< KeyEventArgs>(这一点,的KeyUp),其中(参数=> args.EventArgs.Key == Key.OemPeriod)。
VAR repeatGuard = FALSE;
keyUpStream.Subscribe(X => repeatGuard = FALSE);
keyDownStream
.DelayOrCancel(TimeSpan.FromSeconds(2.0),keyUpStream)
。凡(_ => repeatGuard ==假)
。做(_ =>
{
repeatGuard = TRUE;
})
。订阅(
结果=>
{
Console.WriteLine(KeyHold);
}
);
公共静态类JustinsRx
{
公共静态的IObservable< T> DelayOrCancel< T,TCancel>(此的IObservable< T>源,
时间跨度延迟,
的IObservable< TCancel>取消)
{
//参数检查跳过
从s源返回
从我在Observable.Timer(延迟).TakeUntil(取消)
选择S;
}
}
这工作,但我觉得它可能会更短。
VAR firstKeyDowns =观测
.Merge(keyDownStream.Select(_ =>D),keyUpStream.Select(_ =>'U'))
.DistinctUntilChanged()
。凡(C =以及c =='D');
在firstKeyDowns VAR的查询=从s
从我在Observable.Timer(延迟).TakeUntil(keyUpStream)
选择S;
编辑:这是一个不同的版本,我认为这是一个更好一点:
VAR noRepeats =观测
.Merge(keyDownStream.Select(_ =>D),keyUpStream.Select(_ =>'U'))
.DistinctUntilChanged();
VAR的查询= noRepeats
.Throttle(延迟)
。凡(C =以及c =='D');
specifically I am trying to simulate performing an action if the key is held down for a duration greater than Threshold (T).
I am trying to do this using Reactive Extensions .NET (The stable 1.0 version) without state variables.
Here's the marble diagram of my inputs and what I need:
let T = 3 (so 4 dddd without a key up event make up a "key held down")
keyDown: --dddd---dd--d-dddddddddd----
keyUp: -----------u-----u--u---------------u--
desired: --------a---------------a----------
Here's some example code I came up with that works but uses a state variable.
var keyDownStream = Observable.FromEventPattern<KeyEventArgs>(this, "KeyDown").Where(args => args.EventArgs.Key == Key.OemPeriod);
var keyUpStream = Observable.FromEventPattern<KeyEventArgs>(this, "KeyUp").Where(args => args.EventArgs.Key == Key.OemPeriod);
var repeatGuard = false;
keyUpStream.Subscribe(x => repeatGuard = false);
keyDownStream
.DelayOrCancel(TimeSpan.FromSeconds(2.0), keyUpStream)
.Where(_ => repeatGuard == false)
.Do(_ =>
{
repeatGuard = true;
})
.Subscribe(
result =>
{
Console.WriteLine("KeyHold");
}
);
public static class JustinsRx
{
public static IObservable<T> DelayOrCancel<T, TCancel>(this IObservable<T> source,
TimeSpan delay,
IObservable<TCancel> cancel)
{
//argument checking skipped
return from s in source
from i in Observable.Timer(delay).TakeUntil(cancel)
select s;
}
}
This works, but I feel that it could be made shorter.
var firstKeyDowns = Observable
.Merge(keyDownStream.Select(_ => 'd'), keyUpStream.Select(_ => 'u'))
.DistinctUntilChanged()
.Where(c => c == 'd');
var query = from s in firstKeyDowns
from i in Observable.Timer(delay).TakeUntil(keyUpStream)
select s;
EDIT: Here's a different version that I think is a bit nicer:
var noRepeats = Observable
.Merge(keyDownStream.Select(_ => 'd'), keyUpStream.Select(_ => 'u'))
.DistinctUntilChanged();
var query = noRepeats
.Throttle(delay)
.Where(c => c == 'd');
这篇关于使用接收与取消执行延迟作用一次,每个窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!