Wenn, oder wenn, zu Entsorgen HttpResponseMessage beim Aufruf ReadAsStreamAsync?
Ich bin mit dem System.Net.Http.HttpClient
, um einige der client-Seite die HTTP-Kommunikation. Ich habe alle HTTP-an einem Ort, abstrahiert von dem rest des Codes. In einem Fall will ich die Antwort Lesen-Inhalte als stream an, aber der Verbraucher, der stream ist gut isoliert, von wo aus die HTTP-Kommunikation geschieht, und der stream wird geöffnet. In der Stelle, verantwortlich für die HTTP-Kommunikation ich bin die Entsorgung aller von der HttpClient
Zeug.
Dieser unit-test schlägt fehl bei 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
}
Ich in der Regel versuchen, entsorgen Sie alles, was IDisposable
zum frühest möglichen Komfort, aber in diesem Fall, entsorgen Sie die HttpResponseMessage
verfügt auch über die Stream
zurück von ReadAsStreamAsync
.
So scheint es, wie der aufrufende code muss wissen über und den Besitz der response-Nachricht als auch als stream, oder lasse ich die response-Nachricht undisposed und lassen Sie den finalizer mit der Situation umgehen. Weder die option fühlt sich richtig an.
Diese Antwort spricht nicht über die Entsorgung der HttpClient
. Wie über die HttpRequestMessage
- und/oder HttpResponseMessage
?
Bin ich etwas fehlt? Ich bin der Hoffnung, zu halten die Konsum-code unwissend über HTTP, sondern dass alle diese undisposed Objekte herum geht gegen Jahre der Gewohnheit!
- Nur ein Tipp - Nicht alles
IDisposable
entsorgt werden muss - Dies scheint nicht, nichts zu tun haben mit
async
per se. Die Regeln sind die gleichen, so oder so: nicht entsorgen, das Objekt, bis Sie fertig ist. Das gleiche würde gelten, mit der synchronen version. Also, nutzen Sie die zurückgegebenenStream
innerhalb derusing
. Wenn Sie brauchen, um verwenden Sie dieStream
außerhalb des Kontexts, in dem die Anforderung erstellt haben, müssen Sie zum einrichten eines anderen Mechanismus zu verfügen, die zur rechten Zeit. - Also: ich empfehle, nicht verlassen Entsorgung für den finalizer...aber ich beachten Sie, dass Sie nicht die Mühe zu entsorgen
client
sowieso, also, wenn Sie fühlen, nicht die Mühe mit dem anderen Zeug auch nicht. Wie für die Antwort, die Sie Referenz, beachten Sie, dass es sich auf das Szenario, wo Sie die Wiederverwendung derHttpClient
Objekt; ehrlich gesagt, sollte es offensichtlich sein, dass, wenn Sie wiederverwenden möchten, müssen Sie nicht entsorgen Sie es. Die Anleitung sagt nicht, überhaupt etwas darüber, ob es legitim zu lassen das Objekt Entsorgung geschieht über die Fertigstellung (und IMHO ist es sehr schlechte form zu).
Du musst angemeldet sein, um einen Kommentar abzugeben.
In diesem speziellen Fall es gibt keine Finalizer. Weder
HttpResponseMessage
oderHttpRequestMessage
einen finalizer implementieren (und das ist auch gut so!). Wenn Sie don ' T verfügen entweder von Ihnen, werden Sie von der garbage Collection eingesammelt, sobald die GC-kicks, und der Griff Ihrer zugrunde liegenden streams gesammelt werden, sobald das passiert.Solange Sie diese Objekte verwenden, nicht entsorgen. Sobald Sie dies getan haben, entsorgen Sie. Stattdessen wickelte Sie in ein
using
- Anweisung können Sie immer explizit aufrufenDispose
sobald Sie fertig sind. So oder so wird die Konsum-code braucht nicht auf irgendwelche Kenntnisse zugrunde liegenden http-Anfragen..Dispose()
in seinem eigenen Recht. Es ist nur, wenn es einen finalizer aufruft.Dispose()
dass die GC auslösen können entsorgen..Dispose()
- dies passiert nur, wenn der finalizer explizit geschrieben, dies zu tun.Können Sie auch Streams als input-parameter, also der Anrufer hat die vollständige Kontrolle über den Typ des Streams sowie es zur Verfügung. Und jetzt können Sie auch entsorgen httpResponse bevor die Steuerung verlässt die Methode.
Unten ist die extension Methode für HttpClient
Umgang mit Verfügt in .NET ist sowohl in einfach, und schwer. Für Sie sicher.
Streams ziehen diese gleichen Unsinn... Tut Entsorgung der Puffer auch dann automatisch entsorgen Stream gewickelt? Sollte es? Als Verbraucher sollte ich noch wissen, ob es funktioniert?
Wenn ich viel mit diesem Zeug, ich gehe durch einige Regeln:
So, du hast ein HttpClient, ein HttpRequestMessage, und ein HttpResponseMessage. Das Leben eines jeden von Ihnen, und jede Einweg, die Sie machen, müssen respektiert werden. Also, Ihr Stream sollte nie erwarten, um zu überleben außerhalb des Dispoable Lebensdauer HttpResponseMessage, weil Sie nicht instanziieren der Stream.
In deinem obigen Szenario, mein Muster wäre, zu behaupten, dass zu bekommen, der Stream war wirklich nur in einer Statischen.DoGet(uri) - Methode, und den Stream, den du wieder zurückkehren würde, HABEN zu unserer eigenen machen. Das bedeutet, dass ein zweiter Stream, mit der HttpResponseMessage stream .CopyTo würde meine neue Stream (routing durch ein FileStream-oder ein MemoryStream-oder was auch immer am besten zu Ihrer situation passt)... oder etwas ähnliches. Denn:
So verwenden Sie Einwegprodukte wie catch-and-release... machen Sie, Haken Sie die Ergebnisse für sich selbst, lassen Sie Sie so schnell wie möglich. Und nicht zu verwechseln mit der Optimierung für die Richtigkeit, insbesondere aus den Klassen, die Sie nicht selbst Autor.