2012-04-15 10 views
6

से रद्द किए गए भेदभाव को कैसे भेदभाव करते हैं, जब आप चल रहे टाइमर पर expires_from_now() पर कॉल करते हैं, टाइमर रद्द कर दिया जाता है, और एक नया टाइमर कहा जाता है। तो संबंधित हैंडलर को बुलाया जाता है। रद्द किए गए और समाप्त होने वाले टाइमर के बीच हैंडलर में भेदभाव करना आसान है। फिर भी, मैं सोच रहा हूं कि को समाप्त होने और एक रिट्रिज्ड टाइमर के बीच भेदभाव करने का कोई तरीका है। दोनों उदाहरणों में हैंडलर को त्रुटि_कोड operation_aborted के साथ कहा जाता है। या शायद मुझे कुछ विवरण याद आ रहे हैं।आप एक रेट्रिज्जर्ड बूस्ट deadline_timer

नीचे कोड निम्न उत्पादन उत्पन्न करता है:

20120415 21:32:28079507 Main: Timer1 set to 15 s.  
20120415 21:32:28079798 Main: Timer1 set to 12 s.  
20120415 21:32:28079916 Handler1: Timer 1 was cancelled or retriggered.  
20120415 21:32:40079860 Handler1: expired. 

यह पता चलता है कि हैंडलर, क्योंकि एक टाइमर retriggering फोन करेगा ही हैंडलर एक रद्द हैंडलर के लिए कार्यों को लागू करने और इस तरह एक ही निष्पादित करने में सक्षम नहीं है कार्रवाई। जो संभवतः इच्छित व्यवहार नहीं है।

#include <boost/asio.hpp> 
#include <boost/thread.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time/posix_time/posix_time_io.hpp> 
#include <iostream> 

using namespace boost::posix_time; 
using namespace std; 

void handler1(const boost::system::error_code &ec) 
{ 
    if (ec == boost::asio::error::operation_aborted) 
    { 
     cout << microsec_clock::local_time() << " Handler1: Timer was cancelled or retriggered." << endl; 
    } 
    else 
    { 
     cout << microsec_clock::local_time() << " Handler1: Timer expired." << endl; 
    } 
} 

boost::asio::io_service io_service1; 

void run1() 
{ 
    io_service1.run(); 
} 

int main() 
{ 
    time_facet *facet = new time_facet("%Y%m%d %H:%M:%S%f"); 
    cout.imbue(locale(cout.getloc(), facet)); 

    boost::asio::deadline_timer timer1(io_service1, seconds(15)); 
    timer1.async_wait(handler1); 
    cout << microsec_clock::local_time() << " Main: Timer1 set to 15 s." << endl; 
    // now actually run the timer 
    boost::thread thread1(run1); 
    timer1.expires_from_now(seconds(12)); 
    cout << microsec_clock::local_time() << " Main: Timer1 set to 12 s." << endl; 
    // here the timer is running, but we need to reset the deadline 
    timer1.async_wait(handler1); 
    thread1.join(); // wait for thread1 to terminate 
} 
+1

कृपया हमें बताएं कि आप क्या हासिल करना चाहते हैं। बड़ी तस्वीर क्या है? –

+0

मैं कुछ घटना-ट्रिगर टर्न-ऑन देरी को लागू करने की कोशिश कर रहा हूं। मैं इसे बिना किसी रीट्रिगर्ज किए मूलभूत टर्न-ऑन देरी को कार्यान्वित कर सकता हूं। लेकिन यदि आप परिवर्तनीय या समय-देरी बदलते हैं, तो मुझे इसे फिर से शुरू करना होगा। –

+0

और जब आप ऑपरेशन_बॉर्ट नहीं करते हैं, तो कुछ भी क्यों नहीं करते हैं, किसी दिए गए हैंडलर को याद रखें और इसे फिर से सेट करें? –

उत्तर

4

मैं संरचना का उपयोग कर deadline_timer रैपर करने के लिए कक्षा बनाने का सुझाव दूंगा। इसे रद्द करते समय, याद रखने के लिए ध्वज सेट करें इसे रद्द कर दिया गया था। हैंडलर में, ध्वज को रीसेट करें। expires_from_now() का आविष्कार करते समय ध्वज सेट न करें।

#include <boost/asio.hpp> 
#include <boost/thread.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time/posix_time/posix_time_io.hpp> 
#include <iostream> 

class Timer 
{ 
public: 
    Timer(
      const std::string& name, 
      boost::asio::io_service& io_service 
     ) : 
     _name(name), 
     _timer(io_service), 
     _cancelled(false) 
    { 
     _timer.expires_from_now(boost::posix_time::seconds(0)); 
     this->wait(); 
    } 

    void wait() 
    { 
     _timer.async_wait(
       boost::bind(
        &Timer::handler, 
        this, 
        boost::asio::placeholders::error 
        ) 
       ); 
    } 

    void cancel() { 
     _cancelled = true; 
     _timer.cancel(); 
    } 

    void restart() { 
     _timer.expires_from_now(boost::posix_time::seconds(5)); 
    } 

private: 
    void handler(
      const boost::system::error_code& error 
      ) 
    { 
     if (!error) { 
      std::cout << _name << " " << __FUNCTION__ << std::endl; 
      _timer.expires_from_now(boost::posix_time::seconds(5)); 
      this->wait(); 
     } else if (error == boost::asio::error::operation_aborted && _cancelled) { 
      _cancelled = false; 
      std::cout << _name << " " << __FUNCTION__ << " cancelled" << std::endl; 
     } else if (error == boost::asio::error::operation_aborted) { 
      std::cout << _name << " " << __FUNCTION__ << " retriggered" << std::endl; 
      this->wait(); 
     } else { 
      std::cout << "other error: " << boost::system::system_error(error).what() << std::endl; 
     } 
    } 

private: 
    const std::string _name; 
    boost::asio::deadline_timer _timer; 
    bool _cancelled; 
}; 

int 
main() 
{ 
    boost::asio::io_service ios; 
    Timer timer1("timer1", ios); 
    Timer timer2("timer2", ios); 

    boost::thread thread(
      boost::bind(
       &boost::asio::io_service::run, 
       boost::ref(ios) 
       ) 
      ); 

    sleep(3); 
    std::cout << "cancelling" << std::endl; 
    timer1.cancel(); 
    timer2.restart(); 

    thread.join(); 
} 

नमूना सत्र

macmini:stackoverflow samm$ ./a.out 
timer1 handler 
timer2 handler 
cancelling 
timer1 handler cancelled 
timer2 handler retriggered 
timer2 handler 
^C 
macmini:stackoverflow samm$ 
0

मैं किसी भी तरह पता नहीं है और शायद वहाँ यह करने के लिए कोई अच्छा तरीका है (वहाँ प्रलेखन कह रही है कि आप अलग इन दो स्थितियों बता सकते में कुछ भी नहीं है)।

मेरा मानना ​​है कि यह उद्देश्य से किया गया था। एक नया समाप्ति समय के लिए deadline_timer स्थापना, cancells किसी भी पिछले हैंडलर, क्योंकि:

  • कभी कभी यह कुछ पहले से ही टाइमर पर इंतज़ार कर रहा था, तो बताना मुश्किल है, इसलिए यह बताने के लिए वास्तव में क्या होगा मुश्किल होगा, जब आप एक समाप्ति समय निर्धारित करते हैं;
  • शेड्यूल्ड घटनाओं को दो बार चलाने से रोकने का यह एक आसान तरीका है, एक विशेष तरीके से एक और त्रुटि कोड को संभालने की आवश्यकता है और अधिक त्रुटि-प्रवण है।
संबंधित मुद्दे