2012-12-19 7 views
23

Ich habe eine Service-Schnittstelle mit einer Methode, die einen Parameter vom Typ Stream hat. Sollte ich den Stream schließen, nachdem ich alle Daten aus diesem Stream gelesen habe oder wird dies durch die WCF Runtime erledigt, wenn der Methodenaufruf abgeschlossen ist?Ist es notwendig, die Stream of WebInvoke-Methode zu schließen

Die meisten Beispiele, die ich gesehen habe, lesen nur die Daten aus dem Stream, aber nicht Close oder Dispose auf dem Stream aufrufen.

Normalerweise würde ich sagen, ich muss den Stream nicht schließen, weil die Klasse nicht der Besitzer des Streams ist, aber der Grund ist, warum diese Frage ist, dass wir derzeit ein Problem in unserem System untersuchen, das einige Android Clients, die HTTP-Post verwenden, um Daten an diesen Dienst zu senden, haben manchmal offene Verbindungen, die nicht geschlossen sind (Analysiert mit netstat, die ESTABLISHED Tcp-Verbindungen auflisten).

[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; 
    } 

Konfiguration des Service/Bindung

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

Setzen Sie dies als Kommentar, da ich mir nicht 100% sicher bin. Ich denke, du solltest den "Stream" schließen, da die andere Partei ihn nicht schließen kann, bevor er ihn zurückschickt. Mir ist klar, das ist - wie du gesagt hast - kontraintuitiv. Ich glaube auch nicht, dass eine offene TCP Verbindung mit einem 'Stream' verbunden ist, der geöffnet ist ... es könnte gut geschlossen sein. – pleinolijf

+4

@albertjan Gibt es einen Grund, warum du Kommentare auf diese Art schreibst oder kannst du nicht in ganzen Sätzen schreiben? Ich verstehe nicht, was du sagen willst. Könnten Sie bitte etwas ausarbeiten? – seba

Antwort

2

Die Eigenschaft, die das Verhalten des Schließens steuert oder den Parameter nicht zu schließen ist die OperationBehaviorAttribute.AutoDisposeParameters Eigenschaft und verwendet werden kann, aus dem Standardverhalten von wahren abweichen mit in Bezug auf die Stream Parameter wird geschlossen, sobald es die Methode beendet. Dies ist der Grund, warum Sie das explizite Schließen des Parameters nicht oft sehen. Wenn Sie das Standardverhalten überschreiben möchten, können Sie das explizite Steuerelement und close the Stream once the operation has completed über das Ereignis OperationCompleted übernehmen.

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; 
} 

Beachten Sie, dass Sie Ihre eigene Kopie des Stream, keinen Verweis auf die Clients Stream erhalten und somit sind Sie verantwortlich es zu schließen.

Verwandte Themen