2014-11-21 46 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

相關問題