【发布时间】:2013-01-11 12:35:04
【问题描述】:
我正在使用 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到真)。我还有一个 observable endObservable,从同一个源 observable 查询,它在按钮再次释放时产生一个值(状态从 true 变为 false em>)。当 startObservable 产生一个值时,我每 500 毫秒开始一个可观察的时间间隔。我给这些值加上时间戳,并从中获取,直到 endObservable 产生一个值。然后我返回一个对象,该对象保存 startObservable 的值,以及到目前为止已经保存了多长时间。
我对此有一个单元测试,我按住按钮 2 秒钟(使用 TestScheduler),释放它,然后让调度程序继续运行几秒钟。我这样做是为了确保在释放按钮后不再产生任何值。
这是我的测试失败的地方,也是我的问题的主题。在我的测试中,我预计会产生 4 个值(在 0.5 秒、1 秒、1.5 秒和 2 秒之后)。但是,即使我正在使用 TakeUntil(endObservable)(产生 endObservable 的 digitalInputReleasedEventAdapter,在释放按钮后仍然会产生事件> 有自己的一组测试,我相信它会按应有的方式工作)。
我认为我的查询构造不正确。我怀疑这可能与热与冷的可观察物有关。但由于我刚开始使用 RX,我并不完全了解这可能与我在这里遇到的问题有什么关系。
【问题讨论】:
-
看起来您正在以相当复杂的方式进行操作。为什么不只测量两个事件之间的时间
-
我这样做是因为我不知道按钮会被按住多长时间。因此,释放按钮时的事件可能会在 1 或 1000 秒后发生。与此同时,我仍然希望得到中间事件,告诉我它被按下了多长时间,所以应用程序可以做出不同的反应。当按钮被按下 2 秒时我们可能会做一些事情,然后如果它仍然被按住 5 秒后做其他事情。无论如何,我仍在调查它,看起来我的查询正在做它应该做的事情。我会在接下来的几天里在这里发布更新。
-
如果您有一个事件开始时带有时间戳,那么您可以从当前时钟计算持续时间,而没有额外的事件。
标签: c# system.reactive