我已经实现了一个继承boost :: statechart的状态机。当我调用fsm.process_event( some_event() )
期望哪个反应会抛出异常时,事实证明在使用try-catch块处理异常后,我的状态机实例fsm
被终止。也就是说,fsm.terminated()
会返回true
。在某些情况下,我不希望它被终止。就像我希望statemachine抛出异常以通知调用者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
我希望它输出:
{{1}}
答案 0 :(得分:0)
您应该为状态机提供自定义异常处理程序。请参阅此处的提升文档:http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#ExceptionHandling
当抛出异常时,状态机无法知道它是否仍处于有效状态,这就是异常句柄的默认操作是终止sm的原因。您的自定义处理程序可以执行清理/检查以确保sm处于有效状态,并以不同的方式向上传播信息。
就我个人而言,我从未见过有充分理由通过例外将信息传播出SM。这可能很可能是因为我从未在你的特定领域工作,但这里的理由是:
如果事件无关紧要,则忽略它或记录它,同一事件可能与另一个状态相关,而不是当前状态。如果事件无效,即可能永远不会发生或状态不正确,则可以是: