2011-08-08 37 views
11

Tôi gặp sự cố với Webclient.WebClient rất chậm

Nó rất chậm. Mất khoảng 3-5 giây để downloadString từ một trang web. Tôi không gặp bất kỳ sự cố mạng nào.

Đây là WebClient được sửa đổi của tôi.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 

namespace StatusChecker 
{ 
    class WebClientEx: WebClient 
    { 
     public CookieContainer CookieContainer { get; private set; } 

     public WebClientEx() 
     { 
      CookieContainer = new CookieContainer(); 

      ServicePointManager.Expect100Continue = false; 
      Encoding = System.Text.Encoding.UTF8; 

      WebRequest.DefaultWebProxy = null; 
      Proxy = null; 
     } 

     public void ClearCookies() 
     { 
      CookieContainer = new CookieContainer(); 
     } 

     protected override WebRequest GetWebRequest(Uri address) 
     { 

      var request = base.GetWebRequest(address); 
      if (request is HttpWebRequest) 
      { 
       (request as HttpWebRequest).CookieContainer = CookieContainer; 
      } 
      return request; 
     } 
    } 
} 

UPDATE: Trong Wireshark tôi thấy rằng DownladString duy nhất được gửi và nhận vài ngàn gói tin.

+4

WebClient không phải là đặc biệt chậm, vấn đề phải ở một nơi khác ... Có lẽ trang web bạn đang tải xuống chậm? –

+1

Bạn nên thử sử dụng bộ ghi lưu lượng như WireShark để xác định xem sự chậm trễ có thực sự giữa các yêu cầu đơn lẻ và khung phản hồi (do sự chậm trễ của mạng/máy chủ) hay không xảy ra do mã máy khách đang hoạt động sai và gửi quá nhiều yêu cầu hoặc một số logic như vậy lỗi. –

+0

Cũng thực thi nhiều lần tải xuống trong một vòng lặp để 'khởi động' quá trình (loại bỏ nạp các assembly chẳng hạn). –

Trả lời

30

Có thể có hai vấn đề trong tầm tay ở đây (mà tôi cũng đã nhận thấy trong các chương trình của riêng tôi trước đây):

  • Các yêu cầu đầu tiên phải mất một thời gian dài bất thường: Điều này xảy ra bởi vì WebRequest theo mặc định phát hiện và tải các thiết lập proxy trong lần đầu tiên nó bắt đầu, có thể mất nhiều thời gian. Để ngăn chặn điều này, chỉ cần đặt thuộc tính proxy (WebRequest.Proxy) thành null và nó sẽ bỏ qua séc (miễn là bạn có thể truy cập trực tiếp vào Internet)
  • Bạn không thể tải xuống nhiều hơn 2 mục cùng một lúc: Theo mặc định, bạn chỉ có thể có 2 kết nối HTTP đồng thời mở. Để thay đổi điều này, hãy đặt ServicePointManager.DefaultConnectionLimit thành thứ gì đó lớn hơn. Tôi thường đặt điều này thành int.MaxValue (chỉ cần đảm bảo bạn không gửi spam máy chủ với 1.000.000 kết nối).
+1

Đây không phải là câu trả lời đúng trong trường hợp của tôi. Bạn có thể thấy rằng tôi đã đặt proxy thành null. Và tôi không tải xuống 2 mục cùng một lúc. Cũng như thêm vào bài viết của tôi rằng trong Wireshark tôi có thể thấy rằng ứng dụng của tôi gửi và recives hàng ngàn gói cho mỗi một chuỗi tải xuống. Chuỗi là trang web đơn giản như google.com. – Hooch

+0

Nếu nó không chậm bất thường (có nghĩa là các kết nối có cùng tốc độ với các trạng thái keepalives bị tắt), thì nó hoạt động như bình thường. Phải mất thời gian để thực hiện bắt tay, thực hiện yêu cầu, đợi máy chủ tạo phản hồi, sau đó đọc phản hồi. – foxy

+0

Bạn có thể nói cho tôi biết thêm một chút về những người giữ gìn không? Và tại sao ứng dụng của tôi gửi hàng nghìn gói? – Hooch

0

Có thể nó sẽ giúp ai đó. Một số dịch vụ web hỗ trợ nén (gzip hoặc khác). Vì vậy, bạn có thể thêm tiêu đề Accept-Encoding cho các yêu cầu của bạn và sau đó kích hoạt automatic decompression cho cá thể máy khách web. Chrome hoạt động theo cách đó.

0

Có một vài lựa chọn nếu nó có liên quan đến các thiết lập proxy ban đầu được kiểm tra:

  1. Vô hiệu hóa các thiết lập phát hiện proxy tự động trong Internet Explorer
  2. Đặt proxy để null:

    WebClient.Proxy = null

  3. Khi khởi động ứng dụng, hãy đặt webproxy mặc định là rỗng:

    WebRequest.DefaultWebProxy = null;

Trong mã NET cũ thay vì thiết lập để null, bạn sử dụng để viết những dòng này (nhưng rỗng bây giờ ưa thích):

webclient.Proxy = GlobalProxySelection.GetEmptyWebProxy();