以下可观察序列将每个元素添加到 ReplaySubject 中,以便我以后可以访问任何元素,甚至等待 ReplaySubject 的完成。它在达到一个时间跨度后完成收割主体。
ReplaySubject<string> rfidPlayer = new ReplaySubject<string>();
characteristic.WhenNotificationReceived()
.TakeUntil(Observable.Timer(TimeSpan.FromSeconds(1)))
.Subscribe(
onNext: result =>
{
string nextTag = BitConverter.ToString(result.Data);
nextTag = nextTag.Replace("-", "");
rfidPlayer.OnNext(nextTag);
},
onCompleted: () =>
{
rfidPlayer.OnCompleted();
});
我希望序列一直运行到自上次“OnNext”调用以来的给定时间,然后完成。这在各种蓝牙通信场景中非常有用,其中蓝牙设备将向我提供一系列数据,然后停止而没有任何类型的完成消息或事件。在这些情况下,我需要启发式确定序列何时完成,然后自己完成。因此,如果自上次蓝牙通知以来“太长”,我想完成ReplaySubject。
我可以通过创建一个计时器来做到这一点,在收到每个元素时重置它,然后在计时器达到“太长”时完成ReplaySubject,但是我听说创建一个对象并从可观察的订阅中操作它不是线程安全的。
关于如何在“太长”的时间间隔后完成序列的任何建议?
这是一个与我所听到的不是线程安全的版本,但应该按预期工作:
bool reading = true;
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Elapsed += (sender, e) =>
{
reading = false;
};
ReplaySubject<string> rfidPlayer = new ReplaySubject<string>();
characteristic.WhenNotificationReceived()
.TakeWhile(x => reading)
.Subscribe(
onNext: result =>
{
string nextTag = BitConverter.ToString(result.Data);
nextTag = nextTag.Replace("-", "");
timer.Stop();
timer.Start();
rfidPlayer.OnNext(nextTag);
},
onCompleted: () =>
{
rfidPlayer.OnCompleted();
});
根据西蒙娜尔的第一个答案,这似乎是令人满意的:
characteristic.WhenNotificationReceived()
.Timeout(TimeSpan.FromSeconds(1))
.Subscribe(
onNext: result =>
{
string nextTag = BitConverter.ToString(result.Data);
nextTag = nextTag.Replace("-", "");
rfidPlayer.OnNext(nextTag);
},
onError: error =>
{
rfidPlayer.OnCompleted();
});
慕村9548890
侃侃尔雅
UYOU
相关分类