Te „dobre” dokumenty RFC nakazują każdemu klientowi RFC, aby nie korzystał z więcej niż 2 połączeń na hosta ...
Microsoft zaimplementował to w WebClient. Wiem, że można to wyłączyć za pomocą
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
</configuration>
(znalezione na http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 )
Ale jak mogę to zrobić programowo?
Zgodnie z http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx
„Zmiana właściwości DefaultConnectionLimit nie ma wpływu na istniejące obiekty ServicePoint; ma wpływ tylko na obiekty ServicePoint, które są inicjowane po zmianie. Jeśli wartość tej właściwości nie została ustawiona ani bezpośrednio, ani przez konfigurację, wartość domyślna to stała DefaultPersistentConnectionLimit”.
Chciałbym najlepiej skonfigurować limit, kiedy instaluję WebClient, ale samo usunięcie tego smutnego ograniczenia programowo na początku mojego programu też byłoby w porządku.
Serwer, do którego mam dostęp, nie jest zwykłym serwerem WWW w Internecie, ale pod moją kontrolą i w lokalnej sieci LAN. Chcę wykonywać wywołania API, ale nie używam usług sieciowych ani usług zdalnych
Odpowiedzi:
Dzięki kilku wskazówkom z tego miejsca i innych miejsc udało mi się to naprawić w mojej aplikacji, zastępując klasę WebClient, której używałem:
class AwesomeWebClient : WebClient { protected override WebRequest GetWebRequest(Uri address) { HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address); req.ServicePoint.ConnectionLimit = 10; return (WebRequest)req; } }
źródło
System.Net.ServicePointManager.DefaultConnectionLimit
jest lepszym rozwiązaniem, ponieważ nie można założyć, żeWebRequest
jest toHttpWebRequest
, np. Może to byćFileRequest
.dla zainteresowanych:
System.Net.ServicePointManager.DefaultConnectionLimit = x
(gdzie x to żądana liczba połączeń)nie ma potrzeby dodatkowych referencji
po prostu upewnij się, że nazywa się to PRZED utworzeniem punktu obsługi, jak wspomniano powyżej w poście.
źródło
To rozwiązanie pozwala w dowolnym momencie zmienić limit połączeń :
private static void ConfigureServicePoint(Uri uri) { var servicePoint = ServicePointManager.FindServicePoint(uri); // Increase the number of TCP connections from the default (2) servicePoint.ConnectionLimit = 40; }
Za pierwszym razem, gdy ktokolwiek wywołuje ten FindServicePoint , tworzona jest instancja ServicePoint i WeakReference jest tworzone w celu zatrzymania go wewnątrz ServicePointManager . Kolejne żądania kierowane do menedżera dotyczące tego samego Uri zwracają to samo wystąpienie. Jeśli połączenie nie jest używane później, GC czyści je.
źródło
ServicePoint
Jest tracona (wraz z ustawieniami) poMaxIdleTime
Jeśli zauważysz, że obiekt ServicePoint jest używany przez klienta WebClient, możesz zmienić jego limit połączeń. Obiekty HttpWebRequest mają metodę dostępu do pobierania tego, do którego zostały skonstruowane, więc można to zrobić w ten sposób. Jeśli masz szczęście, wszystkie Twoje żądania mogą skończyć się współdzieleniem tego samego ServicePoint, więc będziesz musiał to zrobić tylko raz.
Nie znam żadnego globalnego sposobu na zmianę limitu. Jeśli zmienisz DefaultConnectionLimit wystarczająco wcześnie podczas wykonywania, prawdopodobnie wszystko będzie dobrze.
Alternatywnie możesz po prostu żyć z limitem połączeń, ponieważ większość oprogramowania serwera i tak będzie Cię dławić. :)
źródło
Mamy sytuację dotyczącą powyższej części konfiguracji w App.Config
Aby było to poprawne w aplikacji CONSOLE, dodaliśmy bibliotekę dll odniesienia System.Configuration. Bez odniesienia powyższe było bezużyteczne.
źródło