2016-11-04 16 views
0

Ich bemerke, dass in vielen der Boost ASIO-Beispiele Aufrufe an Funktionen vorgenommen werden, die bei Fehler werfen können, aber kein Versuch/Catch verwendet wird. Zum Beispiel hat die Blockierung UDP-Client Beispiel here die folgende Funktion:Boost ASIO Ausnahme Ausbreitung

void check_deadline() 
    { 
    // Check whether the deadline has passed. We compare the deadline against 
    // the current time since a new asynchronous operation may have moved the 
    // deadline before this actor had a chance to run. 
    if (deadline_.expires_at() <= deadline_timer::traits_type::now()) 
    { 
     // The deadline has passed. The outstanding asynchronous operation needs 
     // to be cancelled so that the blocked receive() function will return. 
     // 
     // Please note that cancel() has portability issues on some versions of 
     // Microsoft Windows, and it may be necessary to use close() instead. 
     // Consult the documentation for cancel() for further information. 
     socket_.cancel(); 

     // There is no longer an active deadline. The expiry is set to positive 
     // infinity so that the actor takes no action until a new deadline is set. 
     deadline_.expires_at(boost::posix_time::pos_infin); 
    } 

    // Put the actor back to sleep. 
    deadline_.async_wait(boost::bind(&client::check_deadline, this)); 
    } 

Die Dokumention für deadline_.expires_at (here) heißt es, dass diese Funktion ein boost :: system :: system_error Ausnahme auslöst.

Wird dies in diesem Beispiel nicht abgefangen, weil es sich lediglich um ein Beispiel handelt, oder werden Ausnahmen, die von solchen Anrufen ausgelöst werden, über einen Aufruf von run, run-one usw. verbreitet? Mit anderen Worten: Ist es ausreichend, den Aufruf an io_service.run() mit einem try catch zu übergeben, um diese Arten von Ausnahmen zu behandeln?

Weiterhin habe ich festgestellt, dass die delidment_.async_wait Dokumentation here besagt, dass der Handler eine Signatur mit einem Verweis auf einen boost :: system :: system_error :: error_code benötigt. Ich sehe keine Referenz oder einen Platzhalter in der Funktion check_deadline().

+0

@sehe - Danke für den Link zu der anderen Frage, aber ich mache immer noch nicht die Verbindung. Vielleicht zur Klarstellung - ich verstehe gemäß der ASIO-Dokumentation, dass Ausnahmen von Handlern über den io_service.run-Aufruf verbreitet werden dürfen. Es scheint mir, dass die in async_wait übergebene Boost-Grenze check_deadline ein Handler ist, aber wird der Aufruf "deadline_.expires_at" in diesem Fall auch als Handler betrachtet? Außerdem weiß ich immer noch nicht, warum die check_deadline-Funktion keine Boost-Fehlercode-Referenz liefert. – pertre

+2

Das größte Problem, das ich sehe, ist, dass Sie mehrere Fragen gestellt haben; Es ist schwer, zielgerichtete, wiederverwendbare Antworten zu geben - das wird vielen Menschen auf diese Weise helfen. 'expires_at' ist offensichtlich nur ein Funktionsaufruf, aber es passiert im Laufe des Handlers (' check_deadline'). – sehe

Antwort

2

basic_deadline_timer::async_wait Dokumentation Zustände:

Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using boost::asio::io_service::post().

Dies bedeutet, dass der Handler von innen io_service::run() aufgerufen wird (in dem Faden, der sie genannt), so wird Ausnahme automatisch Benutzercode und keine spezielle Handhabung propagiert werden soll, benötigt in Asio. Normalerweise enthält das Beispiel zur Vereinfachung keine Fehlerbehandlung.

Sorry, ich weiß nicht, warum error_code Platzhalter im Beispiel nicht angegeben ist. Müsste einen Blick auf Asio-Quellen werfen.

+4

Ausführlichere Informationen zum Handler in der [WaitHandler] (http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/reference/WaitHandler.html) Dokumentation, wenn "h" ein Handler ist und "ec" ist ein L-Wert vom Typ "const error_code", dann muss der Ausdruck "h (ec)" gültig sein. Der von 'bind()' zurückgegebene Funktor akzeptiert Argumente als Wert und ignoriert zusätzliche Argumente. Daher wird Asio den Funktor mit einem 'error_code' aufrufen, aber das Argument wird beim Aufruf der gebundenen Funktion verworfen. –