wake-up-neo.com

Beinhaltet C # endliche Zustandsmaschinen?

Ich habe kürzlich über die boost::statechart Bibliothek (Finite State Machines) gelesen und das Konzept geliebt.

Hat C # einen ähnlichen Mechanismus? Oder kann es mithilfe eines bestimmten Entwurfsmusters implementiert werden?

27
Maciek

Ja, C # hat Iteratorblöcke , die vom Compiler generierte Zustandsmaschinen sind. 

Wenn Sie eine eigene Zustandsmaschine implementieren möchten, können Sie benutzerdefinierte Implementierungen der IEnumerable<T>- und IEnumerator<T>-Schnittstellen erstellen.

Bei beiden Ansätzen wird die Implementierung des iterator-Musters durch .NET Framework hervorgehoben.

0
Andrew Hare

.NET 4 Update 1 unterstützt es jetzt in der folgenden Klasse: System.Activities.Statements.StateMachine

Hier ist ein Tutorial, wie man es benutzt . Hier ist ein hands on lab .

18
Alex

Workflow Foundation (.NET 3.0) hat einen Zustandsmaschinen-Workflow. 4.0 hat derzeit nicht genau dasselbe, aber Sie können auf jeden Fall einen Zustandsmaschinen-Workflow mit 4.0 erstellen. 

8
Will

Ich betreue ein Open-Source-Projekt, das unter anderem eine generische Finite-State-Maschine für .NET implementiert. Es ist auf QuickGraph aufgebaut, so dass Sie viele Algorithmen zur Graphanalyse kostenlos erhalten.

Siehe diese Seite für weitere Informationen zum Projekt und insbesondere " Jolt.Automata: Finite State Machines " für weitere Informationen zu der Funktion.

6
Steve Guidi

Überprüfen Sie Stateless -> http://code.google.com/p/stateless/ . Es ist eine leichte Alternative zum schwereren WWF.

Hier sind ein paar Artikel des Autors des Tools:

Zustandsmaschinen in Domänenmodellen

Parametrisierte Auslöser und Wiedereintrittsstaaten in Staatenlosen

6
J.D.

Die Dinge, die FSMs in der Nähe sind, sind Workflows in .NET 3.5, Workflows sind jedoch nicht genau FSMs.

Die Verwendung von FSMs besteht darin, dass Sie sie explizit in Ihrem Code erstellen können, wodurch sie weniger Fehler verursachen. Außerdem sind einige Systeme von Natur aus FSMs, daher ist es natürlicher, sie so zu codieren.

2
Henri

Windows Workflow Foundation (WF), das Teil der Basisklassenbibliothek in 3.0 und 3.5 ist, enthält einen Workflowentwurf für Statusmaschinen zum Verwalten von Statusmaschinen für Ihre Anwendungen.

Sie haben den Workflow für die kommende Version 4.0 komplett neu geschrieben, und die neuen Klassen WF 4.0 unterstützen keine Zustandsmaschinen nativ, jedoch werden alle Klassen 3.0/3.5 unter 4.0 weiterhin vollständig unterstützt.

1
Bytemaster

Andere Alternative in diesem Repo https://github.com/lingkodsoft/StateBliss verwendete fließende Syntax, unterstützt Trigger.

    public class BasicTests
    {
        [Fact]
        public void Tests()
        {
            // Arrange
            StateMachineManager.Register(new [] { typeof(BasicTests).Assembly }); //Register at bootstrap of your application, i.e. Startup
            var currentState = AuthenticationState.Unauthenticated;
            var nextState = AuthenticationState.Authenticated;
            var data = new Dictionary<string, object>();

            // Act
            var changeInfo = StateMachineManager.Trigger(currentState, nextState, data);

            // Assert
            Assert.True(changeInfo.StateChangedSucceeded);
            Assert.Equal("ChangingHandler1", changeInfo.Data["key1"]);
            Assert.Equal("ChangingHandler2", changeInfo.Data["key2"]);
        }

        //this class gets regitered automatically by calling StateMachineManager.Register
        public class AuthenticationStateDefinition : StateDefinition<AuthenticationState>
        {
            public override void Define(IStateFromBuilder<AuthenticationState> builder)
            {
                builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
                    .Changing(this, a => a.ChangingHandler1)
                    .Changed(this, a => a.ChangedHandler1);

                builder.OnEntering(AuthenticationState.Authenticated, this, a => a.OnEnteringHandler1);
                builder.OnEntered(AuthenticationState.Authenticated, this, a => a.OnEnteredHandler1);

                builder.OnExiting(AuthenticationState.Unauthenticated, this, a => a.OnExitingHandler1);
                builder.OnExited(AuthenticationState.Authenticated, this, a => a.OnExitedHandler1);

                builder.OnEditing(AuthenticationState.Authenticated, this, a => a.OnEditingHandler1);
                builder.OnEdited(AuthenticationState.Authenticated, this, a => a.OnEditedHandler1);

                builder.ThrowExceptionWhenDiscontinued = true;
            }

            private void ChangingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                var data = changeinfo.DataAs<Dictionary<string, object>>();
                data["key1"] = "ChangingHandler1";
            }

            private void OnEnteringHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                // changeinfo.Continue = false; //this will prevent changing the state
            }

            private void OnEditedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnExitedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnEnteredHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {                
            }

            private void OnEditingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
            }

            private void OnExitingHandler1(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
            }

            private void ChangedHandler1(StateChangeInfo<AuthenticationState> changeinfo)
            {
            }
        }

        public class AnotherAuthenticationStateDefinition : StateDefinition<AuthenticationState>
        {
            public override void Define(IStateFromBuilder<AuthenticationState> builder)
            {
                builder.From(AuthenticationState.Unauthenticated).To(AuthenticationState.Authenticated)
                    .Changing(this, a => a.ChangingHandler2);

            }

            private void ChangingHandler2(StateChangeGuardInfo<AuthenticationState> changeinfo)
            {
                var data = changeinfo.DataAs<Dictionary<string, object>>();
                data["key2"] = "ChangingHandler2";
            }
        }
    }

    public enum AuthenticationState
    {
        Unauthenticated,
        Authenticated
    }
}

0
mcdm