2005.09.01

Response.End() と Response.Close() の違い

都合により、ファイルのダウンロード等とかかわる Response.End() と
ThreadAbortException 例外について調べている。
(少々道を外れてきた気がするが)

検索すると、やはり Response.End() で“例外”が発生することに気づいたための
回避策からか、Response.Close() を使っている場合がいくつか散見される。


てことで、以下のようにしてみた。

Try
  Response.Write("@@1")
  Response.Flush() 'これが無いとエラーになる(ことがある)
  Response.Close()
  Response.Write("@@2")
Catch ex As Exception
  Response.Write("@@3")
  End Try
Response.Write("@@4")


これで、送信されてくるのは @@1 のみ
ただし、コード自体は @@1 / @@2 / @@4 の出力を通っている。
Ethereal で見ると TCP-80のコネクションは .Close() した瞬間に切れているように見える。
TCPのコネクションが切れていて @@3 すら送られてこないので、レンダリング結果も来ない?


比して次の例

Try
  Response.Write("@@1")
  Response.End()
  Response.Write("@@2")
Catch ex As Exception 'ThreadAbortException
  Response.Write("@@3")
End Try
Response.Write("@@4")

この結果、@@1 / @@3 が送信されて来る。(.End() 以降に .Writeしても送られてくる)
TCP-80のコネクション自体は .End() で切れるわけではない。
ただし、Postback の HTMLレンダリングは行われない。
なお、@@4は来ない。再度外側に向かって ThreadAbortException が起きるから。

この通常考えられないような動作の例外(Try/Catch から抜けても、再度自動で発生する)を
どうやって .NET に(言語的に)実装しているか、ということについても興味深いのだが。


これを見る限り、
.End() が ThreadAbortException を投げることで (ごにょごにょしなくても)
通常 Postback で行われる自動的な HTMLレンダリングを『行わなくても良いフラグ』
のように扱われているのに対して
.Close() は単に送り先が無くなって送れませんでした。えへへ。
という動作になっているんじゃないかと推測されるのだな。

どうも、本来 ThreadAbortException “例外”は ASP.NETフレームワーク本体で
 catch されなくてはいけない!
のではないだろうかと感じるようになってきた。
実は、これは“例外”と思ってはいけないんじゃないかと。


なお、.Close() の動作はあくまでも邪推です。
巨大な HTMLにレンダリング画面を作ると、その速度差でわかるかもしれませぬ。

余裕があればまた。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

photo
ichikawa