2012-08-22 60 views
3

我正在使用無狀態框架來創建StateMachine。 我的主應用程序是一個控制檯應用程序,它調用DataManager類,其中 稱爲GetData函數,該函數啓動Task然後用狀態機執行Receiver函數。無狀態Statemachine框架和高CPU使用率

我的問題是,當StateMachine運行時,我得到大約50%的CPU使用率! 當我使用簡單的switch語句實現StateMachine並執行相同的任務 時,它的CPU使用率爲0%! 我有一些編碼錯誤還是無狀態框架的行爲?

該功能的GetData

public List<Byte[]> GetData() 
{ 
    List<Byte> rawData = new List<Byte[]>(); 
    ReceiveTask = Task.Factory.StartNew<List<Byte[]>>(() => Receiver()); 
    //Wait until the Task is complete 

    ReceiveTask.Wait(); 
    //return temp; 
    rawData = ReceiveTask.Result; 

    return rawData; 
} 

DataManager類

public partial class DataManager 
{ 

int _expectedBlocks; 

Byte[] _currentMessage = null; 
Byte[] _firstMessage = null; 
int _currentBlockNumber = 0; 

enum State { Idle, Start, Next, Check, End } 
enum Trigger { DataOK, DataRequest, ReceivingFirstBlock, ReceivingNextBlock, LastPacketReceived, WaitForNext } 

Dictionary<int, Byte[]> _receivedData; 

List<Byte[]> _outputList; 

StateMachine<State, Trigger> _machine; 


private List<Byte[]> Receiver() 
{ 
    _currentMode = Mode.Receive; 
    m_source.MessageReceivedEvent +=new EventHandler<WSANMessageResponseEventArgs>(m_source_MessageReceivedEvent); 
    m_source.StartConnection(); 
    _machine = new StateMachine<State, Trigger>(State.Idle); 

    _receivedData = new Dictionary<int, byte[]>(); 

    _outputList = new List<byte[]>(); 

    //Config StateMachine 
    _machine.Configure(State.Idle) 
     .OnEntry(() => OnIdle()) 
     .OnExit(() => ExitIdle()) 
     .Permit(Trigger.ReceivingFirstBlock, State.Start); 

    _machine.Configure(State.Start) 
     .OnEntry(() => OnStart()) 
     .Permit(Trigger.ReceivingNextBlock, State.Next); 

    _machine.Configure(State.Next) 
     .OnEntry(() => OnNext()) 
     .Permit(Trigger.WaitForNext, State.Start) 
     .Permit(Trigger.LastPacketReceived, State.Check); 

    _machine.Configure(State.Check) 
     .OnEntry(() => OnCheck()) 
     .Permit(Trigger.DataOK, State.End) 
     .Permit(Trigger.DataRequest, State.Idle); 

    _machine.Configure(State.End) 
     .OnEntry(() => OnEnd()); 


    while (_machine.State != State.End) 
    { 

    } 
    _currentMode = Mode.Idle; 
    return _outputList; 
} 

問候 邁克爾

回答

3

更改等待循環

 while (_machine.State != State.End) 
    { 
     Thread.Sleep(10); // Only check once in a while 
    } 

另一種非循環高效的方法;

創建一個ManualResetEventSlim對象;

ManualResetEventSlim mre = new ManualResetEventSlim(false); 

等待循環變化

mre.Wait(); // Waits untill the mre is signaled 

而當_machine.State成爲State.End應該調用

mre.Set(); 

將信號侍者會引起MRE。等待()停止等待

0

您的CPU爲50%,因爲您有2個內核,並且線程爲consumin g與while循環中的100%相同。

switch語句沒有等待循環,所以它不消耗CPU。

不用手動等待,只需實現Event-Based Asynchronous Pattern(EAP)

  • 馬克接收機()爲無效,從而return語句應該被刪除。
  • 在DataManager類上聲明一個事件,如「OperationDone」。
  • 在steate機器的最後一步用_outputList觸發事件。
  • 捕獲事件以返回值。

現在唯一的CPU消耗將由狀態機框架完成。

另一個有用的鏈接:如何:Wrap EAP Patterns in a Task