ฉันจะลบขีด จำกัด การเชื่อมต่อ 2 รายการใน WebClient โดยทางโปรแกรมได้อย่างไร


88

RFC "ดี" เหล่านี้ได้รับคำสั่งจากไคลเอ็นต์ RFC ทุกตัวว่าระวังอย่าใช้การเชื่อมต่อมากกว่า 2 รายการต่อโฮสต์ ...

Microsoft นำสิ่งนี้ไปใช้ใน WebClient ฉันรู้ว่ามันสามารถปิดได้ด้วย

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 )

แต่ฉันจะทำแบบเป็นโปรแกรมได้อย่างไร?

Accordin ไปที่ http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

"การเปลี่ยนคุณสมบัติ DefaultConnectionLimit ไม่มีผลกับอ็อบเจ็กต์ ServicePoint ที่มีอยู่ แต่จะส่งผลต่ออ็อบเจ็กต์ ServicePoint ที่เริ่มต้นหลังจากการเปลี่ยนแปลงเท่านั้นหากไม่ได้ตั้งค่าของคุณสมบัตินี้โดยตรงหรือผ่านคอนฟิกูเรชันค่าดีฟอลต์จะเป็นค่าคงที่ DefaultPersistentConnectionLimit"

ฉันต้องการที่ดีที่สุดในการกำหนดค่าขีด จำกัด เมื่อฉันติดตั้ง WebClient แต่เพียงแค่ลบข้อ จำกัด ที่น่าเศร้านี้ออกทางโปรแกรมเมื่อเริ่มต้นโปรแกรมของฉันก็ใช้ได้เช่นกัน

เซิร์ฟเวอร์ที่ฉันเข้าถึงไม่ใช่เว็บเซิร์ฟเวอร์ทั่วไปในอินเทอร์เน็ต แต่อยู่ภายใต้การควบคุมของฉันและในระบบ LAN ภายใน ฉันต้องการเรียก API แต่ฉันไม่ได้ใช้บริการเว็บหรือระยะไกล


15
มันไม่ได้มาตรฐานจริงๆ RFC "แนะนำ" ให้คุณ จำกัด ไคลเอนต์ไว้ที่การเชื่อมต่อสองครั้ง แต่ไม่ใช่ข้อกำหนดจริงๆ เป็นไปได้ว่าโปสเตอร์ต้องดาวน์โหลดมากกว่า 2 รายการในครั้งเดียว
Erik Funkenbusch

12
ฉันเข้าถึง API บนเซิร์ฟเวอร์ของฉันเอง ฉันไม่ต้องการทำร้ายโฮสต์ในอินเทอร์เน็ต
คริสเตียน

12
ฉันได้เพิ่มขีด จำกัด การเชื่อมต่อเพื่อสร้างเครื่องมือทดสอบการโหลด มันยากมากที่จะโหลดการทดสอบด้วยการเชื่อมต่อ 2 แบบ ฉันแน่ใจว่ามีเหตุผลมากมายที่ไม่เรียกดูเพื่อใช้การเชื่อมต่อจำนวนมาก
ScottS

1
BTW การกำหนดค่าข้างต้นจะส่งผลต่อการเชื่อมต่อที่ควบคุม. Net ทั้งหมดไม่ใช่เฉพาะเว็บไคลเอนต์
ScottS

2
ทำไมมากกว่าสอง? มาดูคำถามกันว่าทำไมฉันไม่สามารถส่งคำขอไปยังเซิร์ฟเวอร์มากกว่าสองรายการในเวลาเดียวกันแบบอะซิงโครนัสได้ 2 เป็นเพียงข้อ จำกัด อย่างแท้จริง
Csaba Toth

คำตอบ:


50

ด้วยเคล็ดลับบางประการจากที่นี่และที่อื่นฉันสามารถแก้ไขสิ่งนี้ในแอปพลิเคชันของฉันได้โดยการแทนที่คลาส WebClient ที่ฉันใช้:

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

28
IMHO ที่การตั้งค่าSystem.Net.ServicePointManager.DefaultConnectionLimitเป็นทางออกที่ดีกว่าที่จะไม่สามารถสันนิษฐานได้ว่าWebRequestเป็นเช่นมันอาจจะเป็นHttpWebRequest FileRequest
Dennis

120

สำหรับผู้ที่สนใจ:

System.Net.ServicePointManager.DefaultConnectionLimit = x (โดยที่ x คือจำนวนการเชื่อมต่อที่คุณต้องการ)

ไม่จำเป็นต้องมีการอ้างอิงเพิ่มเติม

ตรวจสอบให้แน่ใจก่อนที่จะสร้างจุดบริการตามที่ระบุไว้ข้างต้นในโพสต์


สามารถเพิ่มสิ่งนี้ใน application_start ใน global ได้หรือไม่? ดังนั้นมันจึงส่งผลต่อการเชื่อมต่อทั้งหมด?
TheAlbear

จะเพิ่ม System.Net.ServicePointManager.DefaultConnectionLimit = x ได้อย่างไร?
Arul Sidthan

ผิดปกติความคิดเห็นรหัสสำหรับ DefaultConnectionLimit (การนำทางโดยใช้ F12) บอกว่าค่าเริ่มต้นคือ Int32.MaxValue อย่างไรก็ตามจากการตรวจแก้จุดบกพร่องมันเป็น 2 ตามที่อ้างสิทธิ์
crokusek

7

โซลูชันนี้ช่วยให้คุณสามารถเปลี่ยนขีด จำกัด การเชื่อมต่อได้ตลอดเวลา :

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

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

ทุกคนครั้งที่ 1 นี้เรียกFindServicePointเป็นServicePointเช่นถูกสร้างขึ้นและWeakReferenceถูกสร้างขึ้นเพื่อยึดมั่นในมันภายในServicePointManager การร้องขอในภายหลังไปยังผู้จัดการสำหรับ Uri เดียวกันจะส่งคืนอินสแตนซ์เดียวกัน หากไม่ได้ใช้การเชื่อมต่อในภายหลัง GC จะล้างข้อมูล


1
ปัญหาเดียวของ FindServicePoint คือส่งคืน ServicePoint หนึ่งรายการให้คุณ แต่คุณไม่รู้ว่าจะเป็น ServicePoint เดียวกันกับที่ลูกค้าของคุณได้รับหรือไม่
jeffa00

2
นั่นไม่ใช่ "ปัญหา" เป็นเพียงส่วนหนึ่งของงาน เช่นเดียวกับวิธีแก้ปัญหาทั้งหมดคุณต้องหาวิธีทดสอบสิ่งนั้น วิธีของฉันคือตั้งค่าการตั้งค่าใน. config เป็น "1" สังเกตประสิทธิภาพที่แย่มากและตั้งค่าเป็นรหัส (ตามที่นี่) สังเกตประสิทธิภาพที่ดีขึ้น
Abacus

1
ServicePointจะหายไป (พร้อมกับการตั้งค่าของคุณ) หลังจากMaxIdleTime
โคลิน Breame

5

หากคุณพบว่าวัตถุ ServicePoint ถูกใช้โดย WebClient ของคุณคุณสามารถเปลี่ยนขีด จำกัด การเชื่อมต่อได้ อ็อบเจ็กต์ HttpWebRequest มีตัวเข้าถึงเพื่อดึงอ็อบเจ็กต์ที่สร้างขึ้นเพื่อใช้งานดังนั้นคุณสามารถทำได้ด้วยวิธีนี้ หากคุณโชคดีคำขอทั้งหมดของคุณอาจลงเอยด้วยการแบ่งปัน ServicePoint เดียวกันดังนั้นคุณจะต้องทำเพียงครั้งเดียว

ฉันไม่รู้วิธีทั่วโลกในการเปลี่ยนขีด จำกัด หากคุณแก้ไข DefaultConnectionLimit เร็วพอในการดำเนินการคุณอาจจะสบายดี

อีกวิธีหนึ่งคือคุณสามารถใช้ชีวิตได้ด้วยขีด จำกัด การเชื่อมต่อเนื่องจากซอฟต์แวร์เซิร์ฟเวอร์ส่วนใหญ่จะเร่งคุณอยู่แล้ว :)


เซิร์ฟเวอร์นี้จะไม่บีบเค้นฉัน (อันที่จริงมันจะ แต่ในทางที่แตกต่างออกไป) เพราะมันอยู่ภายใต้การควบคุมของฉันอย่างสมบูรณ์
คริสเตียน

1
เซิร์ฟเวอร์อาจเค้นด้วยการเชื่อมต่อจำนวนมาก แต่ฉันยังไม่เคยสัมผัสกับเซิร์ฟเวอร์ขนาดเล็ก (โฮสต์ใน VM ที่ จำกัด ) ขีด จำกัด 2 ในฝั่งไคลเอ็นต์รั้งฉันไว้ในทางกลับกัน การเพิ่มขีด จำกัด ปลดปล่อยสถานการณ์
Csaba Toth

1
ฉันยังสงสัยว่าเบราว์เซอร์ใด ๆ ในปัจจุบันจะปฏิบัติตามขีด จำกัด ของ HTTP 1.1 RFC ที่ 2
Csaba Toth

4

เรามีสถานการณ์เกี่ยวกับส่วนกำหนดค่าข้างต้นใน App.Config

เพื่อให้สิ่งนี้ถูกต้องในแอปพลิเคชัน CONSOLE เราได้เพิ่ม dll อ้างอิง System.Configuration หากไม่มีการอ้างอิงข้างต้นก็ไร้ประโยชน์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.