17

これは私が先週調査してきた問題であり、解決策を見つけることができません。同じことを求めているが答えが得られない投稿が見つかりました。これが他の人にも役立つことを願っています。

内部にWCF含まれるオブジェクトを返すサービスがあります。ストリーミング転送とMtomをstream使用して、クライアントに送信します。basicHttpBinding

クライアントはWCFサービスを呼び出し、応答オブジェクトを受信した直後にプロキシを閉じます。

次に、クライアントはWCFサービスから取得したストリームを読み取り、ローカルディスク上のファイルに書き込みます。これはすべて正常に機能します。

私の問題は、クライアントが操作を中止してWCFサービスからのデータのダウンロードを停止したい場合です。.close()ストリームを呼び出すと、たとえば次のようになります。serverReply.DataStream.Close();次に、WCFサービスからストリーム全体をブロックして読み取り、続行する前に終了します。ストリームは非常に大きくなる可能性があり、ネットワークは常に高速であるとは限りません。

これは、ネットワークリソースの使用量の両方にとって非常に望ましくありません。ネットワークリソースの使用量は、基本的に、使用されなくなったデータで無駄になります。またbasicHttpBinding、WCFサービスサーバーへの同時TCP接続は(デフォルトで)2つしか許可されないため、ストリームが最後まで読み取られるまで、他の接続の試行をブロックします。

同時接続の数を増やすことはできますが、それは問題の可能性を生み出すため、悪い解決策になります。

たとえば、20回のダウンロードが中止されましたが、データをダウンロードして破棄しています。転送を完全に停止する必要があります。

クライアントでは、ストリームオブジェクトは単なる通常Streamのクラスであるため、closeメソッドのみがあり、他には何もありません。

プロキシオブジェクトを呼び出し.close()たり、プロキシオブジェクトを使用したりしても、または他のメソッド.abort()を使用してオブジェクトを破棄することはできません。.dispose()サーバー側では、OperationContext.OperationCompletedイベントを処理しますが、からのデータstreamが最後まで読み取られるまで発生しません。

だから問題は、ストリームを完全に読まずにストリームを閉じる/中止するにはどうすればよいですか?

4

3 に答える 3

1

調査の結果、WCF クライアントは closeTimeout が経過するまでストリームから読み取り続け、その後接続を中止することがわかりました。問題を最小限に抑えるために、クライアントの closeTimeout を減らすことができます。

注: ストリームを破棄するコードは、try/catch ブロックにラップする必要があります。stream.Dispose() メソッドは、 Dispose メソッドで例外をスローしないというガイドラインを破る TimeoutException をスローします。

于 2014-08-12T14:52:04.010 に答える
0

で遊んでみましたbinding.MaxBufferSizeか?
app.config ファイルの設定をいじってみましたか。

<bindings>
  <wsHttpBinding>
    <binding name="default" maxReceivedMessageSize="2147483647"  maxBufferPoolSize="2147483647" 
             closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" >
      <readerQuotas  maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384"
                     maxDepth="64" maxStringContentLength="2147483647" />
    </binding>

  </wsHttpBinding>
</bindings>

タイムアウトとバッファの長さを最小限に抑え、中止または閉じて、何が起こるかを確認します。

于 2012-07-31T18:22:27.967 に答える