2015-09-16 49 views
0

好吧我確定我沒有正確使用狀態機,但這裏是示例代碼的子集。這是曾經是bbvcommon.StateMachine的Appccelerate.StateMachine。用計時器加速狀態機狀態

fsm.In(State.Idle) 
    .ExecuteOnEntry(() => { 
     // wake up and check if there are people still standing and if so restart 
     if(currentlyTalkingTo.Count() > 0) 
     { 
      fsm.Fire(Event.PersonFound); 
     } 
    }) 
    .On(Event.PersonFound).Goto(State.WaitToRecognizePeople); 

fsm.In(State.WaitToRecognizePeople) 
    .ExecuteOnEntry(() => { 
     Thread.Sleep(1000); 
     fsm.Fire(Event.TimeOut); 
    }) 
    .On(Event.TimeOut).Goto(State.Greet); 

問題是處理睡眠的最佳方式是什麼?使用此代碼在關閉應用程序時調用fsm.Stop()有時會掛起應用程序。評論狀態中的所有Thread.Sleeps()可修復問題,以便應用程序成功關閉。

處理需要超時並轉移到另一個狀態的狀態的推薦方法是什麼?示例代碼將不勝感激。

+0

通常,如果您發現自己在代碼中執行過'Thread.Sleep(...)',那麼您可能會做錯某些事情。我對你正在使用的框架並不熟悉,但通常用狀態機做這件事的方法是啓動一個計時器,這個計時器會在一段時間後改變狀態,這種狀態轉換應該調用你當前的代碼在你睡了之後。 – Enigmativity

+0

Thread.Sleep呼叫是否完全阻止關機,或者只是將呼叫延遲至睡眠呼叫中指定的時間(最長)?如果是後者,你可以使用一個事件並等待,而不是睡覺。這樣可以讓您在關機時發出事件信號,從而立即喚醒等待(睡眠)狀態機,以便可以立即關閉它。 –

回答

0

Thread.Sleep會阻止狀態機,即PassiveStateMachineActiveStateMachine,這樣您就不會在休眠時間內對其他事件做出反應。這可能是一個解釋,爲什麼打電話Stop有時掛起解釋。

我假設你不只是想等待一段時間,而是想在超時情況下等待一些事件。然後我會推薦在WaitToRecognizePeopleExecuteOnEntry中啓動一個Timer,當時間結束後,會觸發事件Event.Timeout

如果你有很多狀態有相關的超時時間,爲了避免大量重複的代碼,你甚至可以在一個單獨的類中作爲狀態機擴展實現它,就像我在使用這個庫的一個項目中做的那樣。 (見http://www.appccelerate.com/statemachineextensions.html)。