gpt4 book ai didi

c# - 如何使用 RX 实现超时序列?

转载 作者:行者123 更新时间:2023-11-30 20:16:56 27 4
gpt4 key购买 nike

场景如下:通信过来的设备如果在短时间内回调到服务器,则认为已连接。我想创建一个类来封装跟踪此状态的功能。在调用设备时,应重置超时。回调时,确认连接,状态应设置为true,如果回调超时,应设置为false。但是下一次调用应该能够重新设置超时,而不管当前状态如何。

我想通过使用 swithtimeout 的 RX 来实现这一点。但我不知道为什么它停止工作。

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!

我假设内部 Observable 的超时也停止了外部 Observable。因为 outer => lambda 不再被调用。正确的做法是什么?

谢谢

最佳答案

下面是另一种生成 IsConnected 值流而不使用 .TimeOut 的方法:

public class ConnectionStatus
{
private Subject<Unit> pending = new Subject<Unit>();
private Subject<Unit> connected = new Subject<Unit>();

public bool IsConnected { get; private set; }

public ConnectionStatus(CancellationToken token, short timeoutSeconds = 15)
{
pending
.Select(outer =>
Observable.Amb(
connected.Select(_ => true),
Observable.Timer(TimeSpan.FromSeconds(timeoutSeconds)).Select(_ => false)))
.Switch()
.Subscribe(isConnected => IsConnected = isConnected, token);
}

public void ConfirmConnected()
{
connected.OnNext(Unit.Default);
}

public void SetPending()
{
pending.OnNext(Unit.Default);
}
}

Observable.Amb 运算符只是从首先产生值的可观察对象中获取一个值 - 它比使用异常编码更可取。

关于c# - 如何使用 RX 实现超时序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47308073/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com