VB.Net库用户手册

Step 1. 通过 NuGet 下载 Fawdlstty.SMLite

Step 2. 定义两个枚举类,分别代表所有的状态与所有的触发器

Enum MyState
    Rest
    Ready
    Reading
    Writing
End Enum
Enum MyTrigger
    Run
    Close
    Read
    FinishRead
    Write
    FinishWrite
End Enum

Step 3. 定义状态机变量,模板为两个枚举类,参数为初始值

Dim _smb As SMLiteBuilder(Of MyState, MyTrigger) = New SMLiteBuilder(Of MyState, MyTrigger)()

Step 4. 定义状态机的规则,指定具体的某个状态允许触发什么事件

With _smb.Configure(MyState.Rest)

    ' 如果状态由其他状态变成 MyState.Rest 状态,那么触发此方法,初始化状态机时指定的初始值不触发此方法
    .OnEntry(Sub()
                 Console.WriteLine ("entry Rest")
             End Sub)

    ' 如果状态由 MyState.Rest 状态变成其他状态,那么触发此方法
    .OnLeave(Sub()
                 Console.WriteLine ("leave Rest")
             End Sub)

    ' 如果触发 MyTrigger.Run,则将状态改为 MyState.Ready
    .WhenChangeTo(MyTrigger.Run, MyState.Ready)

    ' 如果触发 MyTrigger.Run,忽略
    .WhenIgnore(MyTrigger.Close)

    ' 如果触发 MyTrigger.Read,则调用回调函数,并将状态调整为返回值
    .WhenFunc(MyTrigger.Read, Function(_state As MyState, _trigger As MyTrigger) As MyState
                                  Console.WriteLine ("call WhenFunc callback")
                                  Return MyState.Ready
                              End Function)

    ' 如果触发 MyTrigger.FinishRead,则调用回调函数,并将状态调整为返回值
    ' 需注意,触发时候需传入参数,数量与类型必须完全匹配,否则抛异常
    .WhenFunc(MyTrigger.FinishRead, Function(_state As MyState, _trigger As MyTrigger, _param_ As String) As MyState
                                        Console.WriteLine ($"call WhenFunc callback with param [{_param}]")
                                        Return MyState.Ready
                                    End Function)

    ' 如果触发 MyTrigger.Write,则调用回调函数(触发此方法回调不调整返回值)
    .WhenAction(MyTrigger.Write, Sub(_state As MyState, _trigger As MyTrigger)
                                     Console.WriteLine ("call WhenAction callback")
                                 End Sub)

    ' 如果触发 MyTrigger.FinishWrite,则调用回调函数(触发此方法回调不调整返回值)
    ' 需注意,触发时候需传入参数,数量与类型必须完全匹配,否则抛异常
    .WhenAction(MyTrigger.FinishWrite, Sub(_state As MyState, _trigger As MyTrigger, _param As String)
                                           Console.WriteLine ($"call WhenAction callback with param [{_param}]")
                                       End Sub)
End With

同一个状态下,如果遇到同样的触发器,最多只允许定义一种处理方式,上面代码对定义的触发事件有详细解释。如果不定义触发事件但遇到触发,那么抛异常。

Step 5. 下面开始真正使用到状态机

' 生成状态机
Dim _sm = _smb.Build(MyState.Rest)

' 获取当前状态
Dim _state = _sm.State

' 判断是否允许触发某一个事件
Dim _allow = _sm.AllowTriggering(MyTrigger.Close)

' 触发一个事件
_sm.Triggering (MyTrigger.Run)

' 触发一个事件,并传入指定参数
_sm.Triggering (MyTrigger.Run, "hello")

' 强行修改当前状态,此操作将不会触发OnEntry、OnLeave事件
_sm.State = MyState.Rest

Step 6. 如果用到异步

使用与上面非常相似,下面是指定异步触发回调函数

Dim _smb As SMLiteBuilderAsync(Of MyState, MyTrigger) = New SMLiteBuilderAsync(Of MyState, MyTrigger)()
With _smb.Configure(MyState.Rest)

    ' 与 OnEntry 效果一致,不过这函数指定异步方法,并且不能与 OnEntry 同时调用
    .OnEntryAsync(Async Function() As Task
                      Await Task.Yield()
                      Console.WriteLine ("entry Ready")
                  End Function)

    ' 与 OnLeave 效果一致,不过这函数指定异步方法,并且不能与 OnLeave 同时调用
    .OnLeaveAsync(Async Function() As Task
                      Await Task.Yield()
                      Console.WriteLine ("leave Ready")
                  End Function)

    ' 效果与 WhenFunc 一致,不过这函数指定异步方法
    .WhenFuncAsync(MyTrigger.Read, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken) As Task(Of MyState)
                                       Await Task.Yield()
                                       Console.WriteLine ("call WhenFunc callback")
                                       Return MyState.Ready
                                   End Function)

    ' 效果与 WhenFunc 一致,不过这函数指定异步方法
    .WhenFuncAsync(MyTrigger.FinishRead, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken, _param As String) As Task(Of MyState)
                                             Await Task.Yield()
                                             Console.WriteLine ($"call WhenFunc callback with param [{_param}]")
                                             Return MyState.Ready
                                         End Function)

    ' 效果与 WhenAction 一致,不过这函数指定异步方法
    .WhenActionAsync(MyTrigger.Write, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken) As Task
                                          Await Task.Yield()
                                          Console.WriteLine ("call WhenAction callback")
                                      End Function)

    ' 效果与 WhenAction 一致,不过这函数指定异步方法
    .WhenActionAsync(MyTrigger.FinishWrite, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken, _p1 As String) As Task
                                                Await Task.Yield()
                                                Console.WriteLine ($"call WhenAction callback with param [{_param}]")
                                            End Function)
End With

然后是触发一个事件:

' 异步触发一个事件,并传入指定参数
Await _sm.TriggeringAsync (MyTrigger.Run, "hello")

' 限定异步任务最长执行时间,超时取消
Dim _source = new CancellationTokenSource (TimeSpan.FromSeconds (10))
Await _sm.TriggeringAsync (MyTrigger.Run, _source.Token, "hello")

await异步触发的事件将在所有函数执行完毕之后返回。另外需要注意,同步与异步最好不要混用,使用的不好就很容易导致死锁,最佳实践是统一同步或统一异步。

results matching ""

    No results matching ""