2012-12-19 14 views
23

Mam interfejs usługi z metodą, która ma parametr typu Stream. Czy powinienem zamknąć strumień po przeczytaniu wszystkich danych z tego strumienia lub czy jest to wykonywane przez środowisko wykonawcze WCF po zakończeniu wywołania metody?Czy konieczne jest zamknięcie strumienia metody WebInvoke

Większość przykładów widziałem, czytaj tylko dane ze strumienia, ale nie wywołuj Close ani utwórz w strumieniu.

Zazwyczaj powiedziałbym, że nie muszę zamykać strumienia, ponieważ klasa nie jest właścicielem strumienia, ale powodem jest pytanie o to, że obecnie badamy problem w naszym systemie, że niektóre Klienci z systemem Android, którzy używają protokołu HTTP-Post do wysyłania danych do tej usługi, czasami mają otwarte połączenia, które nie są zamknięte (Analiza za pomocą netstat, która zawiera listę ESTABLISHED połączeń Tcp).

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

konfiguracji usługi/Oprawa

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

Ujmuje to jako komentarz, ponieważ nie jestem w 100% pewny. Myślę, że powinieneś zamknąć 'Stream', ponieważ druga strona nie może go zamknąć przed zwróceniem go tobie. Zdaję sobie sprawę, że jest to - jak pan powiedział - sprzeczne z intuicją. Ponadto, nie sądzę, aby otwarte połączenie TCP było powiązane z 'Strumieniem', które jest otwarte ... mogłoby zostać zamknięte. – pleinolijf

+4

@albertjan Czy istnieje powód, dla którego piszesz komentarze w ten sposób lub po prostu nie możesz pisać w całych zdaniach? Nie rozumiem, co chcesz powiedzieć. Czy mógłbyś rozwinąć? – seba

Odpowiedz

2

nieruchomości, który kontroluje zachowanie zamknięcia lub nie zamykając parametr jest własnością OperationBehaviorAttribute.AutoDisposeParameters i mogą być wykorzystane do odejścia od domyślnego zachowania prawda z dotyczy parametru Stream zamykanego po wyjściu z metody. Z tego powodu często nie widzisz wyraźnego zamknięcia parametru. Jeśli chcesz zastąpić domyślne zachowanie, możesz uzyskać wyraźną kontrolę i close the Stream once the operation has completed przez zdarzenie OperationCompleted.

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

Pamiętaj, że jesteś otrzymaniu własne kopię Stream, a nie odniesienie do klientów Stream a więc jesteś odpowiedzialny za jego zamykania.

Powiązane problemy