Używam HttpWebRequest
i zbieram strumień odpowiedzi. Czy istnieje właściwa metoda usuwania HttpWebRequest
, ponieważ nie zawiera ona metody zamykania lub utylizacji?Czy istnieje właściwy sposób na usunięcie httpwebrequest?
Odpowiedz
Jeśli klasa miał specjalne wymagania utylizacji, byłoby wdrożyć IDisposable. Ponieważ nie implementuje IDisposable, możesz założyć, że nie ma nic szczególnego, co musisz zrobić.
HttpWebRequest nie implementuje IDisposable, więc nie wymaga utylizacji. wystarczy ustawić obiekt httprequest na wartość null, gdy skończysz.
Nadzieja pomaga
Dlaczego ustawić wartość NULL? Po prostu pozwolenie, aby wykraczało poza zakres, wystarczy, by GC je odebrał ... –
httpwebRequest nie implementuje IDisposable, ponieważ może utworzyć strumień, który implementuje IDisposable. W związku z tym nie powinieneś się martwić o jego usunięcie.
Jeśli martwisz się, choć może chcesz używać WebClient, który jest IDisposable:
using (WebClient c = new WebClient())
{
using (Stream stream = c.OpenRead(url))
{
//
}
}
Można użyć:
var webRequest = WebRequest.Create(ActionUrl)
using (var webResponse = webRequest.GetResponse())
{}
dla swojej realizacji. Kiedy użyłem klasy WebRequest do odpalenia wielu żądań w bardzo krótkim czasie, owijanie GetResponse() w bloku przy użyciu uniemożliwia zawieszanie się aplikacji.
Miałem podobne pytanie, a odpowiedzi tutaj nie dostarczyły mi potrzebnych informacji. Więc nawet jeśli istnieje akceptowana odpowiedź, dodam to, czego nauczyłem się, aby pomóc następnemu facetowi.
1) Jako że niektóre z innych odpowiedzi wspominają, można użyć using
dla strumieni zwróconych przez HttpWebRequest/WebRequest. To jest po prostu dobre standardowe programowanie C#.
Ale tak naprawdę nie odnosi się do pytania OP (lub moje), które dotyczyło pozbywania się samego obiektu HttpWebRequest.
2) Pomimo faktu, że funkcja uzyskiwania HttpWebRequest ma nazwę "Utwórz", nie istnieje żaden zgodny mechanizm Destroy, Close, Dispose ani żaden inny mechanizm dostępny do uwolnienia zasobów z utworzonego obiektu.
Jest to zasadniczo obecnie akceptowana odpowiedź.
3) Ale jest tu implikacja pośród wszystkich odpowiedzi, które tutaj (poza strumieniami) nie pozostawiają nic ważnego, aby zostać zamkniętym. potrzebuje. I nie jest to całkowicie poprawne.
Korzystanie ProcMon można zobaczyć TCP Connect
, TCP Send
i TCP Receive
które występują podczas rozmowy GetResponse()
. Tego właśnie mogłem się spodziewać. Ale kiedy pojawia się TCP Disconnect
? Zakładałem, że stanie się to albo po otrzymaniu odpowiedzi, albo, co najgorsze, gdy obiekt otrzyma GC. Ale rzeczywistość jest bardziej interesująca.
Zamiast tego połączenie TCP pozostaje aktywne przez dokładnie 2 minuty po zakończeniu połączenia. Moja pierwsza myśl była taka, jak długo zajmuje to GC, ale nie. Możesz tam siedzieć w pętli GC.Collect() przez te 2 minuty i nie puszcza, dopóki nie minie 2 minuty.Dzięki temu połączenie jest otwarte zarówno na kliencie, jak i na serwerze, i powoduje (trochę) dodatkowy ruch sieciowy przez te 2 minuty, aby utrzymać połączenie przy życiu.
Inną interesującą rzeczą jest to, że pomimo tego, że wywołujesz "Utwórz", nie oznacza to, że konieczne jest utworzenie innego połączenia TCP. Na przykład, rozważ to:
static void Doit(string domain)
{
HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(domain);
using (HttpWebResponse response = (HttpWebResponse)hr.GetResponse())
using (Stream receiveStream = response.GetResponseStream())
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
Console.WriteLine(readStream.ReadToEnd());
}
Teraz, jeśli zgłoszę to z:
Doit("http://www.foo.bar");
Stworzy 1 połączenie TCP. Pozostanie aktywny przez 2 minuty (lub do momentu wyjścia programu). Ale co, jeśli mogę to zrobić:
Doit("http://www.foo.bar");
Thread.Sleep(20000);
Doit("http://www.foo.bar");
Teraz stworzy 1 połączenie do pierwszego połączenia, a następnie ponowneże przyłącze do drugiego naboru. Oznacza to, że połączenie TCP pozostanie aktywne przez łącznie 2:20 minut. Tak więc, mimo że nazywamy "Utwórz", nie tworzy ono połączenia od zera.
Przeważnie jest to dobre. Nawiązanie połączenia (zwłaszcza połączenie HTTPS) może być kosztownym procesem. System, który automatycznie tego unika, jest (prawdopodobnie) dobrą rzeczą. W ten sposób można efektywnie odzyskać html dla strony internetowej, a następnie dowolnego z powiązanych plików pomocy technicznej (pliki css, img itp.) Bez konieczności przechodzenia przez proces łączenia za każdym razem.
Ale co, jeśli serwer, z którym się łączysz, obsługuje tylko ograniczoną liczbę połączeń? Pozostawienie takiego powiązania bez żadnego uzasadnionego powodu może być poważnym problemem. A może ze względów bezpieczeństwa nie możesz pozostawiać otwartych połączeń przez tak długi czas? A może po prostu jesteś analna i chcesz ją zamknąć, gdy tylko skończysz.
W tych przypadkach można eksperymentować z HttpWebRequest.KeepAlive
. Ustawienie tego na false
(domyślnie true
) powoduje, że każdy z powyższych przykładów używa każdego z nich, zamykając je zaraz po zakończeniu. Cały proces Connect/Send/Receive/Disconnect może zakończyć się w mniej niż sekundę.
FYI:
- Chociaż można użyć WebRequest.InitializeLifetimeService uzyskać ILease, zmieniając wartości w leasingu nie wpływa na limity czasu tutaj.
- Zamiast korzystać z WebRequest, możesz użyć WebClient, który obsługuje Dispose. Jednak podstawowe połączenie TCP nadal pozostaje zawieszone przez 2 minuty, nawet po wywołaniu Dispose.
Podsumowując: Mówienie, że nie musisz martwić się o wyłączenie HttpWebClient może być ogólnie prawdziwe, ale są pewne konsekwencje, o których możesz być świadomy. Istnieją dobre powody takiego zachowania, ale nie możesz zdecydować, czy jest to dobre dla twojej aplikacji, jeśli nie wiesz, że tak się dzieje.
FWIW
- 1. Właściwy sposób na usunięcie modułu cieniującego GLSL?
- 2. Czy istnieje sposób na usunięcie oddziału na heroku?
- 3. Czy istnieje sposób na usunięcie opóźnienia kliknięcia na urządzeniach mobilnych?
- 4. Właściwy sposób na usunięcie rekordu w LINQ do encji
- 5. Czy istnieje prosty sposób na usunięcie kompletnego zestawu dokumentów Vespa?
- 6. Czy istnieje sposób na usunięcie użytkowników do aplikacji Facebook?
- 7. Czy istnieje sposób na usunięcie wszystkich połączeń klientów Redis?
- 8. Czy istnieje sposób na usunięcie cudzysłowów w makrze C?
- 9. Czy istnieje sposób na usunięcie wszystkich lepkich opcji w CVS?
- 10. Czy istnieje "właściwy" sposób konwersji django.db.models.query.ValuesListQuerySet do czystej listy?
- 11. Czy to właściwy sposób na wykrycie iPada?
- 12. Czy istnieje właściwy sposób sprawdzenia istnienia pliku/katalogu w Javie?
- 13. Czy istnieje "właściwy" sposób, aby NSTextFieldCell narysował pionowo wyśrodkowany tekst?
- 14. Czy istnieje właściwy sposób resetowania początkowych danych komponentu w vuejs?
- 15. Właściwy sposób na usunięcie wszystkich danych serii z wykresu wysokiej jakości?
- 16. Czy istnieje sposób na usunięcie mechanizmu śledzenia zmian dla pojedynczego obiektu?
- 17. Czy istnieje leniwy sposób na zapisanie funkcji minusa (usunięcie elementów z listy)?
- 18. Czy istnieje prosty sposób na usunięcie kodu HTML z QString w Qt?
- 19. Używając bxslider, czy istnieje sposób na usunięcie lub ukrycie kul w dolnej części slajdu?
- 20. Czy istnieje sposób na usunięcie lub zmianę zmian w historii plików w repozytorium Team Foundation Studio?
- 21. Czy w Linuksie istnieje prosty sposób na usunięcie strony z tekstem z linii poleceń?
- 22. Właściwy sposób inicjowania danych
- 23. Czy używam transformacji Fouriera we właściwy sposób?
- 24. Czy istnieje właściwy sposób na zwrócenie nowej instancji obiektu przez odwołanie w C++?
- 25. Czy to właściwy sposób na znalezienie sumy kontrolnej?
- 26. Czy to właściwy sposób na refaktorowanie modeli tłuszczu ActiveRecord?
- 27. Najbardziej elegancki sposób na usunięcie elementu ciągowego
- 28. Szybki sposób na usunięcie linii w netBeans
- 29. Czy to właściwy sposób korzystania z History.js?
- 30. Czy używam transformacji identyfikatora we właściwy sposób?
Istnieją scenariusze, w których nie wychodzi to natychmiast poza zakres zastosowania - szczególnie gdy tworzysz wiele żądań internetowych w krótkim okresie czasu . Jeśli musisz go wyrzucić, po prostu wyrzuć go do 'IDisposable', a następnie wywołaj metodę' Dispose() '. –
@ patrz, to nie ma znaczenia. 'HttpWebRequest' nie implementuje' IDisposable'. –