Wie man ein thread warten, bis eine variable erreicht mit einer Reihe von Werten .NET/Csharp
Ich geschrieben habe eine Klasse, die eine Eigenschaft des Typs TProperty
und ein Ereignis vom Typ Action<TProperty>
dass feuert, wenn diese Eigenschaft sich ändert. TProperty
ist in der Regel ein enum-Typ, aber das sollte keine Rolle spielen.
Ich möchte erstellen Sie eine Methode mit der Signatur
bool WaitUntilPropertyIs(int TimeoutMs, IEnumerable<TProperty> AllowedValues)
blockiert der thread, der nannte es, bis die änderungen der Eigenschaft auf einen Wert, der in AllowedValues
. Natürlich, wenn WaitUntilPropertyIs wird aufgerufen, wenn die Eigenschaft ist bereits einer der AllowedValues
sollte es keine Sperrung. WaitUntilPropertyIs
warten soll, bei den meisten TimeoutMs
aus und gibt false zurück wenn die Wartezeit überschritten wird (normal AutoResetEvent.Wait
Semantik).
Ich bin offen mit Reactive Extensions oder traditionelle Synchronisations-Konstrukte.
Die Klasse I im Sinne der ursprünglichen Frage hat einer state-Maschine. Die Eigenschaft beobachtet wird, ist der Zustand der state machine. Manchmal ist die operation, die ich durchführen möchten auf die Klasse kann nur erfolgen in bestimmten Staaten. So WaitUntilPropertyIs pausiert den aktuellen thread, bis die Instanz der Klasse wechselt in den entsprechenden Zustand.
InformationsquelleAutor sevzas | 2011-10-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Rx ist overkill für diese Art von Szenario. Sie können es über
ManualResetEvent
oderManualResetEventSlim
. Sie können Muster für Ihre Lösung die folgende:Ich weiß nicht, Ihre genauen Anforderungen, obwohl, so betrachten Sie den code ändern, der oben zum Schutz vor race conditions.
InformationsquelleAutor Ilian
In Rx + ReactiveUI, dies wird erreicht über:
Wenn wir hinzufügen wollten, ein timeout + ein boolescher Wert, der angibt, dass die Eigenschaft tatsächlich, wir könnten dies tun:
Catch
mithilfe der überlastung derTimeout
braucht man einother
Beobachtbar zu verwenden, wenn das timeout erreicht ist..Timeout(TimeSpan.FromSeconds(5), Observable.Return(false))
Noch besser!
InformationsquelleAutor Paul Betts
Entschied ich mich zu wickeln, alle diese Funktionen in einer Klasse, so kann ich es wiederverwenden in anderen Orten. Dieser code funktioniert der trick.
Auf den Konstruktor übergeben CurrentValueFunc die muss liefert den aktuellen Wert der beobachteten Variablen auf die Nachfrage, pass in IsValueAcceptableFunc muss true zurückgeben, wenn der aktuelle Wert akzeptabel ist.
Müssen Sie sicherstellen, dass ValueWatcher.ValueUpdated wird immer aufgerufen, wenn sich der Wert ändert.
InformationsquelleAutor sevzas
Einen "Kellner" - Klasse und ein list-style-container sollte man es tun. Sperren Sie die Liste zugreifen und die Eigenschaft setter - /event - /was auch immer mit den gleichen Kritischen Abschnitt. Der Kellner Klasse braucht nur die AllowedValues und ein Ereignis für die Anrufer zu warten auf, (OK, vielleicht ein 'bool check(IEnumerable newAllowedValues)' Helfer).
Dass sollte es sein. In WaitUntilPropertyIs(), acquire CS und überprüfen Sie anhand der Eigenschaft Werte erst sehen, wenn Sie können, lassen Sie einfach die CS und sofort zurück, wenn nicht, der Anrufer hat, um zu warten. Erstellen Sie ein Kellner, Kopie in den vergangen AllowedValues, fügen Sie der Kellner auf die Liste, lassen Sie die CS und warten auf das Ereignis mit der übergebenen timeout-Zeit. Wenn das Ereignis warten Renditen, re-erwerben die CS, entfernen Sie den Kellner aus der Liste, die dispose () - lassen Sie die CS und kehrt mit true/false aus der event-wait-Aufruf.
In der setter/Aktion/was auch immer, erwerben die CS, Durchlaufen der Liste, im Vergleich mit der neuen AllowedValues, Feuer-event auf alle Kellner, wo die neuen Werte erfüllen die Reihe und lassen dann die CS.
Rgds,
Martin
InformationsquelleAutor Martin James
Modell, dass die Eigenschaft als
Behavior
(Klasse von Rx, und ein Allgemeines Konzept in reaktive Programmierung für Werte, die änderungen über einen Zeitraum von Zeit).InformationsquelleAutor Ankur