2016-11-04 76 views
0

我注意到,在许多Boost ASIO示例中,正在对可能抛出错误的函数进行调用,但未使用try/catch。例如,封锁UDP客户端的例子here具有以下功能:提升ASIO异常传播

void check_deadline() 
    { 
    // Check whether the deadline has passed. We compare the deadline against 
    // the current time since a new asynchronous operation may have moved the 
    // deadline before this actor had a chance to run. 
    if (deadline_.expires_at() <= deadline_timer::traits_type::now()) 
    { 
     // The deadline has passed. The outstanding asynchronous operation needs 
     // to be cancelled so that the blocked receive() function will return. 
     // 
     // Please note that cancel() has portability issues on some versions of 
     // Microsoft Windows, and it may be necessary to use close() instead. 
     // Consult the documentation for cancel() for further information. 
     socket_.cancel(); 

     // There is no longer an active deadline. The expiry is set to positive 
     // infinity so that the actor takes no action until a new deadline is set. 
     deadline_.expires_at(boost::posix_time::pos_infin); 
    } 

    // Put the actor back to sleep. 
    deadline_.async_wait(boost::bind(&client::check_deadline, this)); 
    } 

为deadline_.expires_at(here)的机制的文档指出,这个函数抛出一个boost ::系统:: SYSTEM_ERROR例外。

这是不是在这个例子中被捕获,因为它只是一个例子,或者像这样的调用抛出的异常通过调用run,run-one等来传播?换句话说,用try catch来调用io_service.run()是否足以处理这些类型的异常?

此外,我还注意到deadline_.async_wait文档here指出处理程序需要一个引用boost :: system :: system_error :: error_code的签名。我在check_deadline()函数中看不到引用或占位符。

+0

@sehe - 感谢链接到其他问题,但我仍然没有建立连接。也许澄清 - 我明白根据ASIO文档,处理程序的异常允许传播通过io_service.run调用。在我看来,传入async_wait的boost绑定check_deadline是一个处理程序,但是在这种情况下,“deadline_.expires_at”调用也被认为是一个处理程序吗?此外,我仍然不知道为什么check_deadline函数不提供boost错误代码引用。 – pertre

+2

我看到的最大问题是你问了很多问题;很难给出有针对性的,可重复使用的答案 - 这将有助于很多人 - 这种方式。 'expires_at'显然只是一个函数调用,但它发生在你的处理程序('check_deadline')中。 – sehe

回答

2

basic_deadline_timer::async_wait文档状态:

Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using boost::asio::io_service::post().

这意味着该处理器将会从内部io_service::run()调用(调用它的线程),所以异常会被自动传播到用户代码,并没有特殊的处理是需要在Asio内部。通常,为了简化,样本不包含错误处理。

对不起,我不知道为什么样本中没有指定error_code占位符。需要看看Asio的消息来源。

+4

要详细说明处理程序,请按照[WaitHandler](http://www.boost.org/doc/libs/1_62_0/doc/html/booster_asio/reference/WaitHandler.html)文档,如果'h'是处理程序'ec'是'const error_code'类型的左值,那么表达式'h(ec)'必须是有效的。从'bind()'返回的函子接受by-value的参数,并且会默默地忽略额外的参数。因此,Asio会用'error_code'调用函子,但是在调用绑定函数时该参数将被丢弃。 –