2012-12-19 23 views
23

私は、Streamのパラメータを持つメソッドを持つサービスインターフェイスを持っています。このストリームからすべてのデータを読み込んだら、ストリームを閉じるべきですか?これは、メソッド呼び出しが完了したときにWCFランタイムによって行われますか?WebInvokeのストリームメソッドを閉じる必要があります

私が見たほとんどの例では、ストリームからデータを読み込むだけですが、ストリームに対してCloseまたはDisposeを呼び出さないでください。

通常は、クラスがストリームの所有者ではないため、ストリームを閉じる必要はありませんが、理由はこの質問には現在システムの問題を調査しているという理由がありますこのサービスにデータを送信するためにHTTP-Postを使用するAndroidクライアントは、閉じられていないオープンな接続を持つことがあります(netstatで分析され、TST接続の確立が分析されます)。

<webHttpBinding> 
    <binding name="WebHttpBindingConfiguration" 
      transferMode="Streamed" 
      maxReceivedMessageSize="1048576" 
      receiveTimeout="00:10:00" 
      sendTimeout="00:10:00" 
      closeTimeout="00:10:00"/> 
</webHttpBinding> 
+0

私は100%確信していないので、コメントとしてこれを置いてください。私はあなたが 'ストリーム'を閉じなければならないと思います、相手があなたにそれを返す前にそれを閉じることはできません。私はこれがあなたの言ったように、直感的ではないことを認識しています。また、私はオープンtcp接続が 'ストリーム'が開かれていることに関連しているとは思わない。 – pleinolijf

+4

@albertjanあなたがそのようにコメントを書いたり、文章全体を書くことができない理由はありますか?私はあなたが言うことを理解していません。あなたは詳細を教えていただけますか? – seba

答えて

2

決算の動作を制御したり、パラメータを閉じていないことOperationBehaviorAttribute.AutoDisposeParametersプロパティであり、真のデフォルトの動作を持つから逸脱して使用することができますプロパティをバインディングサービスの

[ServiceContract] 
public interface IStreamedService { 
    [OperationContract] 
    [WebInvoke] 
    Stream PullMessage(Stream incomingStream); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, UseSynchronizationContext = false)] 
public class MyService : IStreamedService { 

    public System.IO.Stream PullMessage(System.IO.Stream incomingStream) { 
     // using(incomingStream) { 
     // Read data from stream 
     // } 

     Stream outgoingStream = // assigned by omitted code; 
     return outgoingStream; 
    } 

構成/メソッドが終了すると、Streamパラメータは閉じられているとみなされます。これは、パラメータの明示的な終了を頻繁に見ないことが多い理由です。デフォルトの動作を上書きする場合は、OperationCompletedイベントで明示的に制御し、close the Stream once the operation has completedを指定します。

public Stream GetFile(string path) { 
    Sream fileStream = null;  

    try 
    { 
     fileStream = File.OpenRead(path); 
    } 
    catch(Exception) 
    { 
     return null; 
    } 

    OperationContext clientContext = OperationContext.Current; 
clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args) 
    { 
     if (fileStream != null) 
     fileStream.Dispose(); 
    }); 

     return fileStream; 
} 

あなたがクライアントStreamにご自身Streamのコピーではなく、参照を受けている点に注意してくださいので、あなたはそれを閉じるための責任があります。