WebClient'teki 2 bağlantı sınırını programlı olarak nasıl kaldırabilirim


88

Bu "iyi" RFC'ler, her RFC istemcisinden, ana bilgisayar başına 2'den fazla bağlantı kullanmamaya dikkat etmelerini zorunlu kılar ...

Microsoft bunu WebClient'te uygulamıştır. İle kapatılabileceğini biliyorum

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
 <system.net> 
  <connectionManagement> 
   <add address="*" maxconnection="100" /> 
  </connectionManagement> 
 </system.net> 
</configuration> 

( http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 adresinde bulunur )

Ama bunu programlı olarak nasıl yapabilirim?

Http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx için Accordin

"DefaultConnectionLimit özelliğinin değiştirilmesinin mevcut ServicePoint nesneleri üzerinde bir etkisi yoktur; yalnızca değişiklikten sonra başlatılan ServicePoint nesnelerini etkiler. Bu özelliğin değeri doğrudan veya yapılandırma yoluyla ayarlanmadıysa, varsayılan değer sabit DefaultPersistentConnectionLimit olur."

En iyisi, WebClient'i kullandığımda sınırı yapılandırmak isterim, ancak bu üzücü sınırlamayı programımın başlangıcında programla kaldırmak da iyi olur.

Eriştiğim sunucu internette normal bir web sunucusu değil, benim kontrolüm altında ve yerel ağda. API çağrıları yapmak istiyorum ancak web hizmetleri veya uzaktan erişim kullanmıyorum


15
Bu gerçekten bir standart değil. RFC, istemcileri iki bağlantıyla sınırlamanızı "önerir", ancak bu gerçekten bir gereklilik değildir. Büyük olasılıkla, posterin bir seferde 2'den fazla öğe indirmesi gerekiyor.
Erik Funkenbusch

12
Kendi sunucumdan bir API'ye erişiyorum. İnternetteki ev sahiplerine zarar vermek istemiyorum.
Christian

12
Bir yük test aracı oluşturmak için bağlantı sınırını artırdım. 2 kızamık bağlantı ile testi yüklemek gerçekten zor. Eminim birçok bağlantıyı kullanmak için göz atılmayan birçok neden vardır.
ScottS

1
BTW, yukarıdaki yapılandırma yalnızca web istemcisini değil, tüm .Net kontrollü bağlantıları etkileyecektir.
ScottS

2
Neden ikiden fazla? Şu soruyu tersine çevirelim: neden eşzamansız olarak bir sunucuya aynı anda ikiden fazla istek gönderemiyorum? 2 tam anlamıyla bir sınırlamadır.
Csaba Toth

Yanıtlar:


50

Buradan ve başka yerlerden bazı ipuçları ile, kullandığım WebClient sınıfını geçersiz kılarak bunu uygulamamda düzeltmeyi başardım:

class AwesomeWebClient : WebClient {
    protected override WebRequest GetWebRequest(Uri address) {
        HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
        req.ServicePoint.ConnectionLimit = 10;
        return (WebRequest)req;
    }
}

28
IMHO bu ayarı System.Net.ServicePointManager.DefaultConnectionLimitdaha iyi bir çözüm olarak kabul edemeyiz WebRequestbir olduğunu HttpWebRequest, örneğin, bir olabilir FileRequest.
Dennis

120

ilgilenenler için:

System.Net.ServicePointManager.DefaultConnectionLimit = x (burada x, istediğiniz bağlantı sayısıdır)

ekstra referanslara gerek yok

bunun, yukarıda da belirtildiği gibi hizmet noktası oluşturulmadan ÖNCE çağrıldığından emin olun.


Bu, global olarak application_start'a eklenebilir mi? yani yapılan tüm bağlantıları etkiliyor mu?
TheAlbear

System.Net.ServicePointManager.DefaultConnectionLimit = x nasıl ve nereye eklenir?
Arul Sidthan

Garip bir şekilde, DefaultConnectionLimit (F12 kullanarak gezinme) için kod yorumu, varsayılan değerinin Int32.MaxValue olduğunu söylüyor. Ancak, hata ayıklama incelemesi ile iddia edildiği gibi 2'dir.
crokusek

7

Bu çözüm, bağlantı sınırını istediğiniz zaman değiştirmenize olanak tanır :

private static void ConfigureServicePoint(Uri uri)
{
    var servicePoint = ServicePointManager.FindServicePoint(uri);

    // Increase the number of TCP connections from the default (2)
    servicePoint.ConnectionLimit = 40;
}

Biri bu FindServicePoint'i ilk kez çağırdığında , bir ServicePoint örneği oluşturulur ve onu ServicePointManager içinde tutmak için bir WeakReference oluşturulur . Aynı Uri için yöneticiye yapılan sonraki istekler aynı örneği döndürür. Bağlantı daha sonra kullanılmazsa, GC onu temizler.


1
FindServicePoint ile ilgili tek sorun, size bir ServicePoint vermesidir, ancak istemcinizin aldığı ServicePoint ile aynı olup olmayacağını bilmiyorsunuz.
jeffa00

2
Bu bir "sorun" değil, sadece işin normal bir parçası. Tüm çözümlerde olduğu gibi, bunu test etmenin bir yolunu bulmalısınız. Benim yöntemim, .config'deki ayarı "1" olarak ayarlamak, korkunç performansı gözlemlemek ve iyileştirilmiş performansı gözlemleyerek kodu (burada olduğu gibi) ayarlamaktı.
Abacus

1
ServicePointSonra (ayarlarınıza ile birlikte) kaybolurMaxIdleTime
Colin Breame

5

WebClient'ınız tarafından kullanılan ServicePoint nesnesini bulursanız, bağlantı sınırını değiştirebilirsiniz. HttpWebRequest nesneleri, kullanmak üzere oluşturuldukları nesneyi almak için bir erişimciye sahiptir, böylece bunu bu şekilde yapabilirsiniz. Şanslıysanız, tüm istekleriniz aynı ServicePoint'i paylaşabilir, bu nedenle bunu yalnızca bir kez yapmanız gerekir.

Sınırı değiştirmenin küresel bir yolunu bilmiyorum. DefaultConnectionLimit'i yürütme sırasında yeterince erken değiştirdiyseniz, muhtemelen sorun yaşamazsınız.

Alternatif olarak, çoğu sunucu yazılımı sizi her halükarda boğacağından, bağlantı sınırıyla yaşayabilirsiniz. :)


Bu sunucu, tamamen kontrolüm altında olduğu için beni boğmayacak (aslında öyle, ama farklı bir şekilde)
Christian

1
Bir sunucu çok fazla bağlantıyla boğulabilir, ancak küçük bir sunucuda bile (sınırlı bir VM'de barındırılan) bunu deneyimlemedim. Öte yandan müşteri tarafındaki limit 2 beni geride tuttu. Sınırın artırılması durumu özgürleştirdi.
Csaba Toth

1
Ayrıca, günümüzün herhangi bir tarayıcısının HTTP 1.1 RFC'nin 2 sınırına uyacağından da şüpheliyim.
Csaba Toth

4

App.Config'te yukarıdaki yapılandırma parçasıyla ilgili bir durumumuz var

Bunun bir CONSOLE Uygulamasında geçerli olması için System.Configuration referans dll'sini ekledik. Referans olmadan yukarıdakiler işe yaramazdı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.