2009-09-13 5 views
5

Tôi có một số mã khá đơn giản tải lên ảnh hoặc video tới điểm cuối (sử dụng HTTP PUT hoặc POST). Mỗi khi tôi thường thấy kết nối đóng cửa ngoại lệ ném, và trong thực tế các hình ảnh/video đã được tải lên tốt, nó gọi GetResponse nơi ngoại lệ xảy ra.Tại sao HttpWebRequest GetResponse chặn trong một thời gian dài như vậy?

Một điều tôi nhận thấy là GetResponse có thể mất nhiều thời gian để xử lý. Thường dài hơn thời gian tải lên thực tế của ảnh lên máy chủ. Mã của tôi ghi vào máy chủ web bằng cách sử dụng RequestStream.Write.

Tôi đã làm một bài kiểm tra nhỏ và tải lên khoảng 40 ảnh/video cho máy chủ có kích thước từ 1MB đến 85MB và thời gian để GetResponse trở lại là từ 3 đến 40 giây.

Câu hỏi của tôi là, điều này có bình thường không? Đây có phải chỉ là vấn đề máy chủ tôi tải lên các tệp này trong bao lâu để xử lý yêu cầu của tôi và trả lời? Khi xem xét các dấu vết của Fidder HTTP, nó có vẻ như vậy.

FYI, cập nhật của tôi là HTTP 1.0, giá trị Timeout thiết lập để Infinite (cả Timeout và ReadWriteTimeout)

+1

Omar: Nếu bạn nhấp chuột phải vào một phiên trong Fiddler và chọn "Properties", bạn có thể xem bộ sưu tập Thời Gian cho phiên đó.Hai giá trị thú vị là "ServerGotRequest" và "ServerBeginResponse". Đồng bằng giữa chúng là gì? – EricLaw

Trả lời

6

Nếu máy chủ là thực sự mất nhiều thời gian để trả lại bất kỳ dữ liệu nào (như được hiển thị trong Fiddler) thì đó là nguyên nhân của nó. Tải lên tệp đính kèm 85MB sẽ mất nhiều thời gian để bắt đầu và sau đó máy chủ phải xử lý tệp đính kèm. Bạn không thể làm gì nhiều về điều đó - ngoài việc sử dụng một phương thức không đồng bộ nếu bạn có thể tiếp tục với nhiều công việc hơn trước khi cuộc gọi trả về.

Nó không phải là hoàn toàn rõ ràng những gì Fiddler hiển thị cho bạn mặc dù - là nó hiển thị một thời gian dài trước khi máy chủ gửi phản hồi? Nếu vậy, không có nhiều bạn có thể làm. Tôi ngạc nhiên rằng kết nối đang được đóng lại trên bạn, thừa nhận. Tuy nhiên, nếu bạn không thấy dữ liệu của mình bị ghi vào máy chủ, đó là một vấn đề khác.

Bạn có đang hủy trả lời không? Nếu không, bạn có thể có các kết nối đang được giữ sống. Điều này không nên là một vấn đề nếu nó rõ ràng HTTP 1.0, nhưng đó là nguyên nhân phổ biến nhất của "treo" cuộc gọi web trong kinh nghiệm của tôi.

Về cơ bản, nếu bạn không thải bỏ một số WebResponse thì thường sẽ (ít nhất với HTTP 1.1 và giữ) giữ kết nối. Có một giới hạn về số lượng kết nối có thể được mở cho một máy chủ lưu trữ duy nhất, vì vậy bạn có thể kết thúc chờ đợi cho đến khi một phản ứng trước đó được hoàn thành trước khi tiếp theo có thể tiến hành.

Nếu đây vấn đề, một using tuyên bố đơn giản là câu trả lời:

using (WebResponse response = request.GetResponse()) 
{ 
    ... 
} 
+0

Đúng, đang sử dụng phương thức sử dụng để trả lời và đọc GetResponseStream. Trong trường hợp này, có vẻ như tôi phải sống với thực tế là phải mất một thời gian dài ... –

0

Vâng, thời gian phản ứng có thể dài hơn rất nhiều so với chỉ là thời gian tải lên. Sau khi yêu cầu được gửi đến máy chủ, yêu cầu phải được xử lý và phản hồi phải được trả lại. Có thể có một thời gian trước khi yêu cầu được xử lý, và sau đó tệp thường sẽ được lưu ở đâu đó. Sau đó máy chủ sẽ tạo trang phản hồi được gửi lại.

IIS chỉ xử lý một yêu cầu một lần từ mỗi người dùng, vì vậy nếu bạn bắt đầu tải lên khác trước khi lần đầu tiên được hoàn tất, nó sẽ đợi cho đến khi lần đầu tiên hoàn thành trước khi nó bắt đầu xử lý tiếp theo.

+1

<< IIS chỉ xử lý một yêu cầu tại một thời điểm từ mỗi người dùng >> là hoàn toàn không đúng sự thật. Tôi cho rằng bạn đang nhầm lẫn IIS với đối tượng ASP "Session", đã giữ một mutex có thể dẫn đến hạn chế số lượng trang thực hiện đồng thời cho mỗi người dùng. – EricLaw

+0

@EricLaw: Tôi không biết chính xác phần nào của máy chủ web đang giới hạn động cơ đến một trang cho mỗi người dùng, nhưng vì đây là một câu hỏi .NET mà chúng ta đang nói về các yêu cầu đi qua công cụ ASP.NET. Đó là chắc chắn nhất là máy chủ sẽ chỉ xử lý một yêu cầu tại một thời điểm từ mỗi người dùng. – Guffa