我正在實現一個看起來像HTTP服務器的東西,設計是:對於已經建立的連接,我想重複使用它的幾個請求,所以我開始另一個閱讀任務async_read
當一個請求完成時,它也啓動一個deadline_timer
。如果在60秒內沒有輸入,定時器將被觸發並且連接將被破壞。令我感到困擾的是,在調用連接的析構函數之前,我們調用了設置爲async_read
的回調函數。當任務擁有者被破壞時取消掛起的任務回調調用
所以,我的問題是,有沒有辦法取消掛起的閱讀任務,也就是說,在沒有調用回調函數的情況下破壞連接?
如果上述一般描述是不明確的,詳細的工作流程是如下(碼被附加在底部):
cleanup()
當一個請求完成被調用;- 啓動定時器和
cleanup()
中的另一個閱讀任務; - 如果時間不足,
HandleTimeout()
被調用,並且它調用stop()
; - in
stop()
,乾淨的工作,並且之後,連接實例將被破壞。
但是,第4步之後,callback()
函數將被調用,這是在AsyncRead()
註冊,那麼,有沒有辦法取消的callback()
調用?
代碼:
class Connection : public boost::enable_shared_from_this<Connection>,
private boost::noncopyable {
public:
typedef Connection this_type;
void cleanup() {
timer_.expires_from_now(boost::posix_time::seconds(kDefaultTimeout));
timer_.async_wait(boost::bind(&this_type::HandleTimeout,
shared_from_this(),
boost::asio::placeholders::error));
AsyncRead();
}
void AsyncRead() {
boost::asio::async_read(*socket_, in_, boost::asio::transfer_at_least(1),
boost::bind(&this_type::callback,
shared_from_this(),
boost::asio::placeholders::error));
}
void callback(const boost::system::error_code& e) {
// ...
}
void HandleTimeout(const boost::system::error_code& e) {
if(e == boost::asio::error::operation_aborted)
LDEBUG << "The timeout timer is cancelled.";
else if(e)
LERROR << "Error occurred with the timer, message: " << e.message();
else if(timer_.expires_at()
<= boost::asio::deadline_timer::traits_type::now()) {
LDEBUG << "Connection timed out, close it.";
stop();
}
}
virtual void stop() {
connected_ = false;
socket_->close();
connection_manager_.stop(shared_from_this());
}
private:
// ...
boost::asio::deadline_timer timer_;
};
感謝您的回答,我只想確認是否有辦法做到這一點,現在答案似乎是「不」,是的,我需要一個解決方法來做到這一點。 –
@KelvinHu你能否詳細說明你爲什麼需要不同的行爲?如果在'Connection'銷燬之前只調用'callback()',那麼考慮通過'boost :: weak_ptr'將'Connection'的生命期與回調處理程序解耦。這[回答](http://stackoverflow.com/a/18110168/1053968)演示了一個基本的弱指針綁定器,並且[[]](http://stackoverflow.com/a/19622084/1053968)明確地傳遞了'weak_ptr '給一個處理程序。在任何一種解決方案中,都會調用處理程序_will_,但只有在「連接」處於活動狀態時纔會調用「callback()」。 –