簡體   English   中英

如何防止boost :: statetechart因拋出異常而終止

[英]How to prevent boost::statetechart from terminating due to exception thrown

我實現了繼承boost :: statechart的狀態機。 當我調用fsm.process_event( some_event() ) ,預期該反應會引發異常,結果表明,在使用try-catch塊處理異常后,狀態機實例fsm終止了。 也就是說, fsm.terminated()返回true 在某些情況下,我不希望它終止。 就像當我希望狀態機拋出異常以將未處理事件通知fsm.process_event( irrelevant_event() )的調用者並在事件狀態之前保持其當前狀態一樣。

簡而言之-如何防止boost::statechart在引發異常后終止並保持其在異常狀態之前?

示例代碼:

namespace sc = boost::statechart;
class State;
struct some_event : public sc::event<some_event> { };

class FSM
    : public sc::state_machine< FSM, State, std::allocator<void>, sc::exception_translator<> >
{
public:
    FSM()
    {
        cout<<"FSM::FSM()"<<endl;
    }
    virtual ~FSM()
    {
        cout<<"FSM::~FSM()"<<endl;
    }
};


class State : public sc::simple_state< State, FSM >
{
public:
    State()
    {
        cout<<"State::State()"<<endl;
    }
    virtual ~State()
    {
        cout<<"State::~State()"<<endl;
    }

    typedef boost::mpl::list<
        sc::custom_reaction< some_event >,
        sc::custom_reaction< sc::exception_thrown >
    > reactions;
    sc::result react( const some_event & e)
    {
        cout<<"State::react( const some_event &)"<<endl;
        throw std::exception();
        return this->discard_event();
    }
    sc::result react( const sc::exception_thrown & e)
    {
        cout<<"State::react( const sc::exception_thrown &)"<<endl;
        throw;
        return this->discard_event();
    }
};

int main()
{
    FSM fsm;
    fsm.initiate();

    try
    {
        fsm.process_event(some_event());
    }
    catch(...)
    {
        cout<<"Exception caught"<<endl;
    }


    if(fsm.terminated())
    {
        cout<<"fsm2 is TERMINATED"<<endl;
    }
    else
    {
        cout<<"fsm2 is RUNNING"<<endl;
    }
    return 0;
}

代碼輸出:

FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is TERMINATED

我希望它輸出:

FSM::FSM()
State::State()
State::react( const some_event &)
State::react( const sc::exception_thrown &)
State::~State()
Exception caught
fsm2 is RUNNING

您應該為狀態機提供一個自定義的異常處理程序。 請參閱以下增強文檔: http : //www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#ExceptionHandling

引發異常時,狀態機無法知道它是否仍處於有效狀態,這就是為什么異常句柄的默認操作是終止sm的原因。 您的自定義處理程序可以進行清理/檢查,以確保短信處於有效狀態,並在其他庄園中向上傳播信息。

就我個人而言,我從未見過有充分的理由例外地將信息從SM傳播出去。 這很可能是因為我從未在您的特定領域工作過,但我的合理性仍然是:

如果該事件不相關,則忽略該事件或將其記錄下來,同一事件可能在另一種狀態下是相關的,而不是當前狀態。 如果事件無效,即永遠不會發生或狀態不正確,則可能是:

  • 您的代碼有問題,您應該立即斷言並處理問題
  • 來自包含SM的模塊之外的無效輸入的問題(硬件連續發布3個斷開連接的事件,這永遠不會發生,等等)。 在這種情況下,您無法以任何方式在本地模塊中正確處理異常,最好的辦法是記錄問題並切換到CatastrophicErrorState或只能保留EvReset的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM