Sto usando il System.Net.Http.HttpClient
di fare qualche comunicazione HTTP sul lato client. Ho tutto il HTTP in un punto, astratto rispetto al resto del codice. In un'istanza voglio leggere il contenuto della risposta come uno stream, ma il consumatore dello stream è ben isolato da dove avviene la comunicazione HTTP e lo stream è aperto. Nel posto responsabile della comunicazione HTTP, sto eliminando tutto il materiale HttpClient
.Quando o se eliminare HttpResponseMessage quando si chiama ReadAsStreamAsync?
Questa unità non riuscirà a Assert.IsTrue(stream.CanRead)
:
[TestMethod]
public async Task DebugStreamedContent()
{
Stream stream = null; // in real life the consumer of the stream is far away
var client = new HttpClient();
client.BaseAddress = new Uri("https://www.google.com/", UriKind.Absolute);
using (var request = new HttpRequestMessage(HttpMethod.Get, "/"))
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
//here I would return the stream to the caller
stream = await response.Content.ReadAsStreamAsync();
}
Assert.IsTrue(stream.CanRead); // FAIL if response is disposed so is the stream
}
Io di solito cerco di disporre di tutto ciò IDisposable
al più presto possibile, ma in questo caso, disporre il HttpResponseMessage
dispone inoltre il Stream
tornato da ReadAsStreamAsync
.
Quindi sembra che il codice chiamante debba conoscere e assumere la proprietà del messaggio di risposta e del flusso, oppure lasciare il messaggio di risposta non esposto e lasciare che il finalizzatore lo gestisca. Nessuna delle due opzioni sembra giusta.
This answer parla della mancata disponibilità di HttpClient
. Che ne dite di HttpRequestMessage
e/o HttpResponseMessage
?
mi sto perdendo qualcosa? Spero di mantenere il codice che consuma ignorante di HTTP, ma lasciare tutti questi oggetti non disposti in giro va contro l'anno di abitudine!
Solo un consiglio - Non tutto 'IDisposable' da smaltire –
questo non sembra avere nulla a che fare con' async' di per sé. Le regole sono le stesse in ogni caso: non disporre l'oggetto finché non hai finito. La stessa cosa si applicherebbe usando la versione sincrona. Quindi, usa il 'stream' _inside_ restituito l'' using'. Se è necessario utilizzare il 'Stream' al di fuori del contesto in cui viene creata la richiesta, sarà necessario impostare un meccanismo diverso per eliminarlo al momento giusto. –
Inoltre: non è consigliabile lasciare lo smaltimento per il finalizzatore ...ma noto che non ti preoccupi di eliminare il client in ogni caso, quindi se ti senti a tuo agio, non preoccuparti nemmeno delle altre cose. Per quanto riguarda la risposta a cui si fa riferimento, si noti che si riferisce allo scenario in cui si _retra_ l'oggetto 'HttpClient'; francamente, dovrebbe essere ovvio che se si vuole riutilizzarlo, non lo si può eliminare. La guida non dice nulla sul fatto che sia legittimo lasciare che lo smaltimento degli oggetti avvenga tramite la finalizzazione (e IMHO è una forma molto povera). –