2016-11-04 109 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'調用函子,但是在調用綁定函數時該參數將被丟棄。 –