Używam System.Net.Http.HttpClient
do wykonywania komunikacji HTTP po stronie klienta. Mam wszystkie HTTP w jednym miejscu, oddzielone od reszty kodu. W jednym przypadku chcę odczytać zawartość odpowiedzi jako strumień, ale konsument strumienia jest dobrze odizolowany od miejsca, w którym odbywa się komunikacja HTTP i strumień jest otwarty. W miejscu odpowiedzialnym za komunikację HTTP pozbywam się wszystkich rzeczy z HttpClient
.Kiedy lub kiedy wyrzucić HttpResponseMessage podczas wywoływania ReadAsStreamAsync?
Jednostka ta nie powiedzie się 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
}
ja zazwyczaj staram się wrzucać wszystkiego IDisposable
na możliwie najwcześniejszym wygody, ale w tym przypadku umieszczenia HttpResponseMessage
dysponuje również Stream
wrócił z ReadAsStreamAsync
.
Wygląda na to, że kod wywoławczy musi wiedzieć i przejąć na własność wiadomość z odpowiedzią, a także strumień, lub pozostawić wiadomość z odpowiedzią i nie pozwolić, by finalizator sobie z nią poradził. Żadna z tych opcji nie wydaje się właściwa.
This answer mówi o nie wyrzucaniu HttpClient
. Co powiesz na HttpRequestMessage
i/lub HttpResponseMessage
?
Czy brakuje mi czegoś? Mam nadzieję, że zachowam niedostrzegalny kod HTTP, ale pozostawienie tych wszystkich nieporządanych obiektów wbrew zwyczajowi!
Tylko końcówka - Nie wszystko 'IDisposable' należy wyrzucać –
ten wydaje się nie mieć nic wspólnego z' async' per se. Zasady są takie same w każdym przypadku: nie wyrzucaj obiektu, dopóki go nie skończysz. To samo dotyczyłoby wersji synchronicznej. Tak więc użyj zwróconego 'Stream' _inside_ the" using ". Jeśli chcesz użyć 'Stream' poza kontekstem, w którym tworzone jest żądanie, musisz skonfigurować inny mechanizm, aby usunąć go we właściwym czasie. –
Ponadto: nie polecam pozostawiania utylizacji dla finalizatora ...ale zauważam, że i tak nie trudzisz się wyrzucaniem 'klienta', więc jeśli nie masz nic przeciwko temu, nie przejmuj się innymi rzeczami. Jeśli chodzi o odpowiedź, na którą się powołujesz, zauważ, że dotyczy ona scenariusza, w którym "korzystasz" z obiektu 'HttpClient'; Szczerze mówiąc, powinno być oczywiste, że jeśli chcesz go ponownie użyć, nie pozbądź się go. Wskazówki nie mówią nic o tym, czy dozwolone jest po prostu oddanie obiektu przez sfinalizowanie (a IMHO jest bardzo słaba). –