场景如下:如果设备在短时间内向服务器发出回调,则认为该设备正在通信中。我希望创建一个类来封装这种状态跟踪的功能。当调用设备时,超时应该被重置。回调时,确认连接,并将状态设置为true;如果回调超时,则应将其设置为false。但是下一次调用应该能够重新设置超时时间,而不考虑当前的状态。
我想使用RX和
这是一个“测试用例”:
我假设内部可观察对象的超时也会停止外部可观察对象。因为
谢谢。
我想使用RX和
switch
以及timeout
来实现这个功能。但我不知道为什么它停止工作了。public class ConnectionStatus
{
private Subject<bool> pending = new Subject<bool>();
private Subject<bool> connected = new Subject<bool>();
public bool IsConnected { get; private set; }
public ConnectionStatus(CancellationToken token, short timeoutSeconds = 15)
{
pending.Select(outer => connected.Timeout(TimeSpan.FromSeconds(timeoutSeconds)))
.Switch()
.Subscribe(_ => IsConnected = true, e => IsConnected = false, token);
}
public void ConfirmConnected()
{
connected.OnNext(true);
}
public void SetPending()
{
pending.OnNext(true);
}
}
这是一个“测试用例”:
var c = new ConnectionStatus(default(CancellationToken));
c.SetPending();
await Task.Delay(TimeSpan.FromSeconds(5));
c.ConfirmConnected();
c.IsConnected.Dump(); // TRUE, OK
c.SetPending();
await Task.Delay(TimeSpan.FromSeconds(5));
c.ConfirmConnected();
c.IsConnected.Dump(); // TRUE, OK
c.SetPending();
await Task.Delay(TimeSpan.FromSeconds(20));
c.IsConnected.Dump(); // FALSE, OK
c.ConfirmConnected();
c.IsConnected.Dump(); // FALSE, OK
c.SetPending();
await Task.Delay(TimeSpan.FromSeconds(10));
c.ConfirmConnected();
c.IsConnected.Dump(); // FALSE, NOT OK!
我假设内部可观察对象的超时也会停止外部可观察对象。因为
outer =>
lambda表达式不再被调用。正确的方式是什么?谢谢。
Select
后面加上.FirstOrDefaultAsync()
。如果没有它,即使connected
已经提交了值,超时仍然会被触发。与此同时,我已经找到了另一个解决方案:pending.Select(_ => connected.Buffer(TimeSpan.FromSeconds(timeoutSeconds), 1).FirstOrDefaultAsync()) .Switch().Subscribe(l => IsConnected = l.Count > 0, token);
- ZorgoZFirstOrDefaultAsync
? - Shlomo