Làm cách nào để tôi có thể xóa giới hạn 2 kết nối theo chương trình trong WebClient


88

Những RFC "tốt" đó yêu cầu từ mọi RFC-client rằng họ phải cẩn thận không sử dụng nhiều hơn 2 kết nối trên mỗi máy chủ ...

Microsoft đã triển khai điều này trong WebClient. Tôi biết rằng nó có thể được tắt bằng

App.config:

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

(tìm thấy trên http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 )

Nhưng làm thế nào tôi có thể làm điều đó theo chương trình?

Accordin vào http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

"Thay đổi thuộc tính DefaultConnectionLimit không ảnh hưởng đến các đối tượng ServicePoint hiện có; nó chỉ ảnh hưởng đến các đối tượng ServicePoint được khởi tạo sau khi thay đổi. Nếu giá trị của thuộc tính này chưa được đặt trực tiếp hoặc thông qua cấu hình, giá trị sẽ được mặc định thành DefaultPers phù hợpConnectionLimit không đổi."

Tốt nhất là tôi muốn định cấu hình giới hạn khi cài đặt WebClient, nhưng chỉ cần xóa giới hạn đáng buồn này theo lập trình khi bắt đầu chương trình của tôi cũng sẽ ổn.

Máy chủ mà tôi truy cập không phải là một máy chủ web thông thường trên internet, mà nằm trong tầm kiểm soát của tôi và trong mạng lan cục bộ. Tôi muốn thực hiện lệnh gọi API, nhưng tôi không sử dụng dịch vụ web hoặc dịch vụ xóa


15
Nó không thực sự là một tiêu chuẩn. RFC "khuyến nghị" rằng bạn nên giới hạn máy khách ở hai kết nối, nhưng nó không thực sự là một yêu cầu. Nhiều khả năng, người đăng cần tải xuống nhiều hơn 2 mục cùng một lúc.
Erik Funkenbusch

12
Tôi truy cập một API trên máy chủ của riêng mình. Tôi không muốn làm hại các máy chủ trên internet.
Christian

12
Tôi đã tăng giới hạn kết nối để xây dựng một công cụ kiểm tra tải. Thực sự khó để tải thử nghiệm với 2 kết nối máy đo. Tôi chắc rằng có rất nhiều lý do không duyệt để sử dụng nhiều kết nối.
ScottS

1
BTW, cấu hình ở trên sẽ ảnh hưởng đến tất cả các kết nối được kiểm soát bởi .Net, không chỉ webclient.
ScottS

2
Tại sao nhiều hơn hai? Hãy xoay quanh câu hỏi: tại sao tôi không thể đưa ra nhiều hơn hai yêu cầu đến một máy chủ cùng một lúc không đồng bộ? 2 chỉ là một hạn chế theo nghĩa đen.
Csaba Toth

Câu trả lời:


50

Với một số mẹo từ đây và những nơi khác, tôi đã cố gắng khắc phục điều này trong ứng dụng của mình bằng cách ghi đè lớp WebClient mà tôi đang sử dụng:

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

28
IMHO rằng đặt giá trị System.Net.ServicePointManager.DefaultConnectionLimitlà một giải pháp tốt hơn, vì không thể cho rằng cái WebRequestlà a HttpWebRequest, ví dụ, nó có thể là a FileRequest.
Dennis

120

cho những người quan tâm:

System.Net.ServicePointManager.DefaultConnectionLimit = x (trong đó x là số lượng kết nối mong muốn của bạn)

không cần tham khảo thêm

chỉ cần đảm bảo rằng điều này được gọi là TRƯỚC KHI điểm dịch vụ được tạo như đã đề cập ở trên trong bài đăng.


Vì vậy, điều này có thể được thêm vào application_start trên toàn cầu? vì vậy nó ảnh hưởng đến tất cả các kết nối được thực hiện?
TheAlbear

Làm thế nào và ở đâu để thêm System.Net.ServicePointManager.DefaultConnectionLimit = x?
Arul Sidthan

Thật kỳ lạ, bình luận mã cho DefaultConnectionLimit (điều hướng bằng F12) cho biết mặc định của nó là Int32.MaxValue. Tuy nhiên bằng cách kiểm tra gỡ lỗi nó là 2 như đã tuyên bố.
crokusek

7

Giải pháp này cho phép bạn thay đổi giới hạn kết nối bất kỳ lúc nào :

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

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

Lần đầu tiên bất kỳ ai gọi FindServicePoint này , một phiên bản ServicePoint được tạo và một WeakReference được tạo để giữ nó bên trong ServicePointManager . Các yêu cầu tiếp theo đối với người quản lý cho cùng một Uri trả lại cùng một phiên bản. Nếu kết nối không được sử dụng sau đó, GC sẽ xóa nó.


1
Vấn đề duy nhất với FindServicePoint là nó trả lại cho bạn một ServicePoint nhưng bạn không biết liệu nó có giống với ServicePoint mà khách hàng của bạn nhận được hay không.
jeffa00

2
Đó không phải là một "vấn đề", nó chỉ là một phần bình thường của công việc. Như với tất cả các giải pháp, bạn phải tìm cách kiểm tra điều đó. Cách của tôi là đặt cài đặt trong .config thành "1", quan sát hiệu suất khủng khiếp và đặt nó trong mã (như ở đây), quan sát hiệu suất được cải thiện.
Abacus

1
Cái ServicePointbị mất (cùng với cài đặt của bạn) sau khiMaxIdleTime
Colin Breame

5

Nếu bạn thấy đối tượng ServicePoint đang được WebClient của bạn sử dụng, bạn có thể thay đổi giới hạn kết nối của nó. Các đối tượng HttpWebRequest có một bộ truy cập để truy xuất đối tượng mà chúng được xây dựng để sử dụng, vì vậy bạn có thể làm theo cách đó. Nếu bạn may mắn, tất cả các yêu cầu của bạn có thể chia sẻ cùng một ServicePoint nên bạn chỉ phải thực hiện một lần.

Tôi không biết có cách toàn cầu nào để thay đổi giới hạn. Nếu bạn đã thay đổi DefaultConnectionLimit đủ sớm trong quá trình thực thi, có lẽ bạn sẽ ổn.

Ngoài ra, bạn có thể sống với giới hạn kết nối, vì hầu hết các phần mềm máy chủ sẽ hạn chế bạn. :)


Máy chủ này sẽ không ngăn cản tôi (trên thực tế, nó sẽ làm như vậy, nhưng theo một cách khác) vì nó hoàn toàn nằm trong tầm kiểm soát của tôi
Christian

1
Một máy chủ có thể điều tiết với nhiều kết nối, nhưng tôi chưa gặp phải điều đó ngay cả với một máy chủ nhỏ (được lưu trữ trong một máy ảo giới hạn). Mặt khác, giới hạn 2 ở phía khách hàng đã kìm hãm tôi. Tăng giới hạn giải phóng tình hình.
Csaba Toth

1
Tôi cũng nghi ngờ rằng bất kỳ trình duyệt hiện nay sẽ tuân theo để giới hạn HTTP 1.1 RFC của 2.
Csaba Toth

4

Chúng tôi có một tình huống liên quan đến phần cấu hình trên trong App.Config

Để điều này có hiệu lực trong Ứng dụng CONSOLE, chúng tôi đã thêm dll tham chiếu System.Configuration. Nếu không có tài liệu tham khảo, ở trên là vô ích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.