PG日誌

読者です 読者をやめる 読者になる 読者になる

PG日誌

主にc#の事を書いています

WCFの大容量通信でハマった話


WCFでオブジェクトの数が多い(リストに10万件弱)を通信しようとしたところクライアント側で以下のメッセージが表示されました。

System.ServiceModel.CommunicationException: 基礎になる接続が閉じられました: 接続が予期せずに閉じられました ---> System.Net.WebException: 基礎になる接続が閉じられました: 接続が予期せずに閉じられました

この時、やけくそで設定値は死ぬほどでかい数字を設定していました。

項目
MaxBufferSize 209715200
MaxReceivedMessageSize 209715200
MaxStringContentLength 209715200
maxArrayLength 209715200

で、少し調べたら要素数が多いときは

DataContractSerializer.MaxItemsInObjectGraph

を指定しないといけないとのこと。
で、MSDNを調べたところ、以下のページに

DataContractSerializer.MaxItemsInObjectGraph プロパティ (System.Runtime.Serialization)

既定値は、MaxValue です。

とあり、MaxValueのリンク先は

Int32.MaxValue フィールド (System)

となっていました。
そこで、以下ツールを使ってビヘイビアへ設定を追加しました。
構成エディター ツール (SvcConfigEditor.exe)

画面には、2147483647と表示されていたのでそのまま
じゃあということで、保存して構成を保存しました。

その時の出力は以下の通りです。

<behavior name="SampleBehavior">
    <dataContractSerializer/>

通信を試すもまたしても冒頭のエラーが発生。
よーく調べるとどうもこの値、Int32.MaxValueじゃなくて、System.UInt16のMaxValueっぽいですね。

なので、65535件以上扱いたい場合、上記ツールから最大値は入らないので以下のように修正したところ通信可能になりました。(クライアント側ではエラーが出ましたが同じような方法で通信量を大きく設定したら治りました)

<behavior name="SampleBehavior">
    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>

ツールとMSDNの2重攻撃でやられてしまいました。
というか、最初から現実的な値を明示しておけばよかったんですよね。
冒頭の通信設定も頭のねじが飛んでるのでさっさと修正します。