我正在使用 RX 来查询来自自动化设备的事件,该设备连接有按钮。我希望能够区分用户刚刚按下并立即释放按钮,或者他是否按住按钮一段时间。我用来查看他是否按住按钮的查询有问题。
基本思想是一旦按钮被按下,我会每半秒产生一个值,直到按钮再次被释放。我还给每个值加上时间戳,这样我就知道按钮被按下了多长时间。
这是我的代码,以及我认为这应该如何工作:
public IObservable<DigitalInputHeldInfo> Adapt(IObservable<EventPattern<AdsNotificationEventArgs>> messageStream) {
var startObservable =
_digitalInputPressedEventAdapter.Adapt(messageStream);
var endObservable =
_digitalInputReleasedEventAdapter.Adapt(messageStream);
return from notification in startObservable.Timestamp()
from interval in
Observable.
Interval(
500.Milliseconds(),
_schedulerProvider.ThreadPool).
Timestamp().
TakeUntil(endObservable)
select new DigitalInputHeldInfo(
interval.Timestamp.Subtract(notification.Timestamp),
notification.Value);
}
从给定的 IObservable 中,我正在对其应用查询,以便我有一个可观察的startObservable,每次按下按钮时都会产生一个值(状态从false变为true)。我还有一个可观察的endObservable,从同一个源 observable 查询,它在按钮再次释放时产生一个值(状态从true变为false)。当startObservable产生一个值时,我每 500 毫秒开始一个可观察的时间间隔。我给这些值加上时间戳,并从中获取,直到endObservable产生一个值。然后我返回一个包含startObservable值的对象到现在为止已经坚持了多久。
我对此进行了单元测试,我按住按钮 2 秒钟(使用 TestScheduler),释放它,然后让调度程序继续运行几秒钟。我这样做是为了确保在释放按钮后不再产生任何值。
这是我的测试失败的地方,也是我的问题的主题。在我的测试中,我预计会产生 4 个值(在 0.5 秒、1 秒、1.5 秒和 2 秒之后)。但是,即使我使用的是TakeUntil(endObservable) ,在按钮释放后仍然会产生事件(产生 endObservable 的digitalInputReleasedEventAdapter有自己的一组测试,我相信它会按应有的方式工作) .
我认为我没有错误地构建我的查询。我怀疑这可能与热与冷的可观察物有关。但由于我刚开始使用 RX,我并不完全了解这可能与我在这里遇到的问题有什么关系。