【问题标题】:How to use boost's deadline_timer::asynch_wait in a loop?如何在循环中使用提升截止时间计时器::async_wait?
【发布时间】:2015-12-14 02:10:21
【问题描述】:

我有一个 MFC 应用程序 (VC10),我在其中使用了 deadline_timer::asynch_wait() 在一个单独的线程中的 while 循环中运行。由于事实上,等待时间可能是几分钟甚至更长,我正在使用 asych_wait 来中断等待。我的问题是定时器回调只被调用一次,而第一次执行。当循环第二次执行时,回调不再被调用。知道我做错了什么吗?

header:
std::unique_ptr<boost::asio::deadline_timer> m_timer;

cpp:
UINT camThread1( LPVOID pParam )
{
  CDlg* pView = (CMyDlg*) pParam;
  boost::asio::io_service io_service;

  // to be able to interrupt the timer from the GUI Thread
  pView->m_timer.reset(new boost::asio::deadline_timer(io_service)); 

  boost::posix_time::ptime lastLoop;
  typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;
  lastLoop = time_traits_t::now();

  while (1)
  {
    boost::posix_time::ptime nextFrameTime;
    // calculate the time to wait
    nextFrameTime = lastFrameTime + boost::posix_time::seconds(pView->m_interval);

    // start the timer
    pView->m_timer->expires_at(nextFrameTime);
    pView->m_timer->async_wait(boost::bind(&CDlg::timer_handler, pView, boost::asio::placeholders::error));
    io_service.run();

    DWORD dwWaitResult = WaitForSingleObject(pView->m_timerEvent, INFINITE);
    switch (dwWaitResult) 
    {
      // check results
    }
    lastLoop = time_traits_t::now(); // get the current time

    // do something
  }
}

我的计时器回调如下所示:

void CDlg::timer_handler(const boost::system::error_code& error)
{
  if (!error || error == boost::asio::error::operation_aborted)
  {
    SetEvent(m_timerEvent);
  } else {
    //throw std::exception(...);
  }
}

我的活动创建如下:

m_timerEvent = CreateEvent( NULL, FALSE, FALSE, TEXT("timerEvent"));

有什么建议吗?请...

Tnx 提前和欢呼 格雷格

【问题讨论】:

    标签: c++ multithreading boost mfc boost-asio


    【解决方案1】:

    我想我在检查了一些教程/示例并仔细阅读了文档后解决了这个问题。 首先 io_service.run() 调用是阻塞的,直到所有工作完成并且没有更多的处理程序要分派。这使得使用事件的信号化变得不必要!

    其次,io_service.run() 需要在任何第二组或更晚的调用集之前重置! 它现在可以使用以下代码:

    UINT camThread1( LPVOID pParam )
    {
    CDlg* pView = (CMyDlg*) pParam;
    boost::asio::io_service io_service;
    
    // to be able to interrupt the timer from the GUI Thread
    pView->m_timer.reset(new boost::asio::deadline_timer(io_service)); 
    
    boost::posix_time::ptime lastLoop;
    typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;
    lastLoop = time_traits_t::now();
    while (1)
    {
      boost::posix_time::ptime nextFrameTime;
      // calculate the time to wait
      nextFrameTime = lastFrameTime + boost::posix_time::seconds(pView->m_interval);
    
      // start the timer
      pView->m_timer->expires_at(nextFrameTime);
      pView->m_timer->async_wait(boost::bind(&CDlg::timer_handler, pView, boost::asio::placeholders::error));
      if(io_service.stopped()) {
        io_service.reset();
      }
      io_service.run();
    
      lastLoop = time_traits_t::now(); // get the current time
    
      // do something
    }
    

    【讨论】:

    • 那么,timer_handler 是什么?
    • 这就是deadline_timer的处理程序。计时器到期时将调用处理程序。请参阅上面的问题,但除此之外无需设置任何事件!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多