我正在使用boost deadline_timer,出现,在删除拥有对象后调用其处理程序。我已经尝试了几种方法来实现这一点。
首先,我通过使用'shared_from_this'绑定到处理程序和拥有对象来使用计时器
m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
m_timer.async_wait(
boost::bind(&CTcpSslSocket::handle_handshake_timeout,
shared_from_this(),
boost::asio::placeholders::error)
);
此方法使计时器功能正确,但也会导致对拥有对象的引用。我表明我在关闭应用程序时泄漏了拥有的对象。我前一段时间遇到类似的问题,使用弱指针解决了问题(感谢stackoverflow的其他人的帮助)。我通过这样做尝试了同样的事情:
m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
boost::weak_ptr<CTcpSslSocket> weak( shared_from_this() );
m_timer.async_wait([=]( const boost::system::error_code& error ) {
boost::shared_ptr<CTcpSslSocket> strong(weak);
if ( strong ) {
strong->handle_handshake_timeout(error);
}
return;
});
就计时器功能而言,这似乎也能正常工作,但在关闭应用程序时会导致内存损坏。在调试器中运行表明在boost代码调用处理程序时发生了异常。
如果我使用定时器的操作在给定时间内完成,我取消定时器,否则我不对定时器做任何事情。这是取消代码:
if ( m_eHandshakeTimer != eExpired )
{
m_eHandshakeTimer = eCanceled;
m_timer.cancel();
}
关于如何解决这个问题的任何想法?
答案 0 :(得分:0)
当然,持有弱指针并不能保持对象(CTcpSslSocket)活着。
弱指针只能通过共享指针观察拥有的对象的生命周期结束。
改为执行异步操作 share 所有权。这样,当您检测到计时器已被取消时,您将自动释放共享对象。
m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
auto This = shared_from_this();
m_timer.async_wait([=]( const boost::system::error_code& error ) {
if (ec != boost::asio::error::operation_aborted) {
This->handle_handshake_timeout(error);
// ^ could share This with other handlers to keep it alive
}
return;
});