2014-11-21 57 views
1

我正在使用助推deadline_timer,其中出现将在拥有对象被删除后调用其处理程序。我尝试了几种方法来实现这一点。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

当然,持有弱指针并没有使对象(CTcpSslSocket)保持活动状态。

弱指针只能通过共享指针观察对象拥有的的生命周期结束。

使异步操作分享所有权。这样,当您检测到定时器已被取消时,则会自动释放共享对象。

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; 
}); 
+0

感谢 - 但你能解释一下......是不是你的榜样(不是使用拉姆达除外)一样我原来m_timer.async_wait( 的boost ::绑定(CTcpSslSocket :: handle_handshake_timeout, shared_from_this( ), boost :: asio :: placeholders :: error) ); – Ken 2014-11-21 16:47:45

+0

我正在将此标记为答案。乍一看,我认为它与我尝试的第一种方法基本相同,使用'shared_from_this()'。但是这有点不同,原因有两个。首先,'shared_from_this()'实例保存在由lambda捕获的局部变量中,而我试图将其传递给定时器对象。其次,超时处理程序仅在计时器实际超时时才被调用,而不是在其他事件导致处理程序触发时调用。 – Ken 2014-11-21 19:17:31

+0

你是早期的几秒钟:)坚持: – sehe 2014-11-21 19:18:45

相关问题