2016-11-04 5 views
0

多くのブーストASIOの例では、エラーが発生する可能性のある関数が呼び出されていますが、try/catchは使用されていません。 deadline_.expires_at(here)用ブーストASIO例外伝播

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

documentionこの関数はブースト::システム:: SYSTEM_ERROR例外をスローすると述べている:例えば、ブロックするUDPクライアントの例hereには、以下の機能があります。

これは単なる例であるか、このような呼び出しから送出された例外がrun、run-oneなどの呼び出しを介して伝播するため、この例では検出されませんか?つまり、これらのタイプの例外を処理するためにtry catchでio_service.run()に呼び出しをラップするだけで十分ですか?

また、deadline_.async_waitのドキュメントhereには、ハンドラがboost :: system :: system_error :: error_codeへの参照を伴う署名が必要であることが記載されています。 check_deadline()関数で参照やプレースホルダが表示されません。

+0

@sehe - 他の質問へのリンクありがとうございますが、私はまだ接続していません。おそらく明確にする - 私はASIOのドキュメントに従って、ハンドラからの例外がio_service.runコールを通して伝播することが許されていることを理解しています。ブーストバウンドのcheck_deadlineがasync_waitに渡されるのはハンドラですが、この場合はハンドラとも呼ばれる "deadline_.expires_at"コールです。さらに、私はまだcheck_deadline関数がboostエラーコード参照を与えない理由を知らない。 – pertre

+2

私が見る最大の問題は、複数の質問をしたことです。ターゲットとした、再利用可能な回答を与えることは難しく、それは多くの人々をそのように支援します。 'expires_at'は明らかに単なる関数呼び出しですが、ハンドラの途中で発生します(' check_deadline')。 – sehe

答えて

2

basic_deadline_timer::async_waitドキュメントの状態は:

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().

これは、ハンドラは(それを呼び出したスレッドに)内部io_service::run()から呼び出されることを意味し、その例外は、自動的にユーザーコードに伝播され、特別な取り扱いがありませんアシオの中で必要です。通常、サンプルには簡単のためにエラー処理が含まれていません。

申し訳ありませんが、error_codeサンプルにプレースホルダが指定されていない理由はわかりません。 Asioのソースを調べる必要があります。

+4

ハンドラについて詳しくは、[WaitHandler](http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/reference/WaitHandler.html)のドキュメントで、 'h'がハンドラであれば'ec'は' const error_code'型の左辺値であり、式 'h(ec)'は有効でなければなりません。 'bind()'から返されたファンクタは、値渡しの引数を受け取り、余分な引数を黙って無視します。したがって、Asioは 'error_code'でファンクタを呼び出しますが、バインドされた関数を呼び出すときに引数は破棄されます。 –