Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

イベントと例外のセマンティクス

# こういうことを知ったかぶって言うと、「当たり前だろヴォケ」とか「今まで知らなかったの!?」とか言われそうな気がして、ちょっと怖いのだけど。
# というか、.NET Frameworkの挙動がどうなっているか調べずに書いてる。

イベントって何だろう? →何らかのアクションが発生したことを通知する機構。
例外って何だろう? →何らかの操作が、その責務を完了できなかったことを報告する機構。

イベントの処理中に例外が発生するということは、何を意味するんだろう?

例外が発生したということは、その処理は責務を完了できなかったことを示す。
けれど、イベントの責務は「通知すること」だから、イベントが発生した時点で、既にその責務は果たされている。
失敗したのは、イベントの発生を受けて走る処理であって、イベントそのものではない。
だから、イベント(を駆動するOnXXXメソッド)は、例外を外部に伝播させるべきではない?

別の方向から考えてみる。
イベントの実体はMulticastDelegateであり、これには複数のハンドラを結びつけることができる。
この時、各々のハンドラが呼び出される順番は保証されないのではないだろうか。
だとすると、イベントの発生順を期待した処理を組んではならないということになる。つまり、各イベントハンドラは独立しており、他のイベントハンドラと何ら関連性を持たない。
ということは、あるイベントが失敗したところで、他のイベントには関係ないのだから、他のイベントは正常に呼び出されなければならない。
ここから、イベントハンドラ中で発生した例外は握りつぶすべきである、という結論に至る。

さらに別の方向から考えてみる。
Windowsはイベント駆動型OSであり、それはメッセージの送信によって実現されている。
メッセージ送信には、同期と非同期、SendMessageとPostMessageがある。
.NETのイベントとWindowsのイベントが必ずしもイコールとなるわけではないけれど、イベントハンドラがウィンドウプロシージャから呼び出されるとすれば、PostMessageによってポストされたメッセージの処理中に例外が発生した場合、その例外はPostMessageの呼び出し元では捕捉できない。
じゃあその例外はどこに飛んでいくかと言えば、(Windowsの構造化例外処理に従えば)メッセージループを飛び出してスレッドを終了させてしまう(これを捕捉する最終手段、スレッドプロシージャ全体に仕掛けられたハンドラがApplication.ThreadExceptionなのだろう、たぶん)。
よって、(Windowsメッセージによって駆動される)イベントでは、例外を発生させるべきではない。

しつこく別の方向から考えてみる。
イベントの実体はデリゲートである。であれば、何故デリゲートだけでなく、イベントという機構がわざわざ用意されたのだろう?
この2つは、仕組み的には同じである。ならば、意味的に違うのではないか?
イベントの意味が「発生した時点で責務を全うするもの」ではないかということは既に書いた。
そして、非同期処理(Stream.BeginReadとか)で使われるデリゲートで発生した例外は、一旦保留され、その処理を完了するタイミング(Stream.EndReadとか)に中継されるようになっている。
つまり、イベントではないデリゲートでは、例外を発生させてはならないということはない。
イベントとデリゲートには、例外処理に関して意味的な違いがあるのではないだろうか。だからこそ、わざわざイベントというものを用意したのではないだろうか。

投稿日時 : 2007年6月29日 15:59

Feedback

# re: イベントと例外のセマンティクス 2007/06/29 16:19 黒龍

鋭い。戻りもvoidだし呼び出し側はあとはしらねーよって事ですね。

# re: イベントと例外のセマンティクス 2007/06/29 16:41 シャノン

なるほど。非同期処理の EndXXX は戻り値を持ちますからね。
こいつは戻り値を返せない事態に遭遇したら例外を投げる必要があるということでしょう。

# re: イベントと例外のセマンティクス 2007/06/29 17:14 黒龍

呼んでる人に誤解があったらアレなので補足。
正常系、準正常系など想定できる範囲での例外は投げるべきではないということですね。
握りつぶせ!って思い込んじゃうといけないと思ったので補足でした。

# re: イベントと例外のセマンティクス 2007/10/22 7:08 Odysseas

Nice

タイトル
名前
Url
コメント