2012-12-19 15 views
23

Ho un interfaccia del servizio con un metodo che ha un parametro di tipo Stream. Dovrei chiudere lo stream dopo aver letto tutti i dati da questo stream o questo è stato eseguito dal WCF Runtime quando la chiamata al metodo è stata completata?E 'necessario chiudere il flusso del metodo di WebInvoke

Gli esempi più che abbia mai visto, fare solo leggere i dati dal flusso, ma non invito a chiudere o gettare sul Stream.

Normalmente direi che non è necessario chiudere il flusso perché la classe non è il proprietario del flusso, ma la ragione è perché si pone questa domanda è che stiamo attualmente esaminando un problema nel nostro sistema, che alcuni I client Android, che utilizzano HTTP-Post per inviare dati a questo servizio, talvolta hanno connessioni aperte che non vengono chiuse (analizzato con netstat che elenca le connessioni Tcp ESTABLISHED).

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

Configurazione del servizio/Binding

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

Mettendo questo come commento, dato che non sono sicuro al 100%. Penso che dovresti chiudere il 'Stream', in quanto l'altra parte non può chiuderlo prima di restituirlo a te. Mi rendo conto che questo è ... come tu hai detto ... contro-intuitivo. Inoltre, non penso che una connessione tcp aperta sia correlata a un 'stream' che è aperto ... potrebbe benissimo essere chiuso. – pleinolijf

+4

@albertjan C'è una ragione per cui scrivi commenti in questo modo o non riesci proprio a scrivere in frasi intere? Non capisco cosa vuoi dire. Potresti per favore elaborare? – seba

risposta

2

La proprietà, che controlla il comportamento di chiusura o non chiusura del parametro è la proprietà OperationBehaviorAttribute.AutoDisposeParameters e può essere utilizzato per deviare dal comportamento predefinito di vero con Per quanto riguarda il parametro Stream viene chiuso una volta che esce il metodo. Questo è il motivo per cui spesso non vedi la chiusura esplicita del parametro. Se si desidera sovrascrivere il comportamento predefinito, è possibile assumere il controllo esplicito e close the Stream once the operation has completed tramite l'evento 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; 
} 

Tenete a mente che si sta ricevendo il vostro proprio copia del Stream, non un riferimento ai clienti Stream e, quindi, di essere responsabile per la chiusura.