System.Net.Sockets.SocketException

どんなエラー?

HttpClientのソケットエラー。sqlなどのコネクションとは性質が異なるので注意。sqlのデータプロバイダーはコネクションをプールに返すまでアイドル状態(※1)を維持している。4分(※2)たっても再接続がない場合は、自動的にコネクションは閉じられる。
対して、HttpClientのソケットは、スコープを抜けた瞬間にコネクションを閉じるフローに入る。4分かけたのちに完全にクローズする形だ。なので、異なるスコープが発生する都度、同一ソケットを使用する場合は4分間待ってからopen、という非常に面倒な手続きを踏むことになる。この手続きを踏まないで、DBコネクションのように再接続を試みると、ソケットエラーになる。

※1 アイドルの水泳大会の話ではない。
※2 デフォルト値。レジストリで管理。

対応方法

ソケットを殺さないのが基本。マイクロソフト的には、インスタンス生成時にソケットを開いて、インスタンスを破棄するときにソケットクローズになるような設計を推奨しているようだ。まぁ、端的に言うと、コンストラクタで処理してメンバーで保持しろってこと。

あとは、この4分間というソケットクローズ待機時間に、新しいソケットが大量に作成されない工夫が必要になる。ソケットの最大数はレジストリで設定可能だが、無尽蔵に増やせるというものではない。当然のこと、サーバーのスペックに合わせた設定値があるわけで、上限値に達した場合は、以降の接続はソケットエラーとなる。

レジストリの値を触って、4分間というクローズ時間を短くすることも可能だが、この設定に関してはマイクロソフトは否定的のようだ。まあ、通信を全く理解していないバカのやること、で済ますことも可能だが、一応補足。この否定的な考えに至った理由は下記となる。

通信っていうのは、サーバーとクライアント間で行われているものなのだから、クローズの命令が発せられたからと言ってflush(電文を流すの意味)が終わったわけではない。そのための猶予時間は必ず必要なのだ。サーバー側の適正値のみで測れる猶予時間ではない。

コンピュータ同士の思いやり時間みたいなものだと思えば、このエラーが出たときにほっこり?するんじゃないだろうか。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です