Das Szenario sieht wie folgt aus: Ein Gerät, das kommuniziert, gilt als verbunden, wenn es innerhalb kurzer Zeit zum Server zurückwechselt. Ich möchte eine Klasse erstellen, die die Funktionalität enthält, diesen Status zu verfolgen. Bei einem Anruf an das Gerät sollte das Timeout zurückgesetzt werden. Beim Rückruf wird die Verbindung bestätigt, und der Status sollte auf true festgelegt werden. Wenn der Rückruf abgelaufen ist, sollte er auf false gesetzt werden. Aber der nächste Anruf sollte in der Lage sein, das Zeitlimit wieder gleichgültig zum aktuellen Status zu setzen.Wie erreiche ich die Abfolge von Timeouts mit RX?
Ich dachte, dies mit RX mit swith
und timeout
zu erreichen. Aber ich weiß nicht, warum es aufhört zu arbeiten.
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);
}
}
Dies ist die „Testfall“:
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!
Ich gehe davon aus, dass das Timeout des inneren beobachtbaren auch die äußere beobachtbare anhält. Als outer =>
Lambda wird nicht mehr aufgerufen. Was ist der richtige Weg?
Danke
Vielen Dank. Ich habe Ihren Vorschlag getestet und festgestellt, dass nach 'Select' ein' .FirstOrDefaultAsync() 'benötigt wird. Ohne es wird das Timeout auch nach dem 'connected' mit dem Wert ausgelöst. Ich habe inzwischen eine andere Lösung gefunden: 'pending.Select (_ => connected.Buffer (TimeSpan.FromSeconds (timeoutSeconds), 1) .FirstOrDefaultAsync()) .Switch(). Abonnieren (l => IsConnected = l.Count> 0 , Token); ' – ZorgoZ
Ihre andere Lösung sollte auch funktionieren. – Shlomo
In welchem Fall wurde 'FirstOrDefaultAsync' benötigt? – Shlomo