2009-11-27 24 views
5

Tôi cố gắng để gửi một số nội dung cho khách hàng trước khi thực hiện một số công việc dài:Response.Flush() chỉ làm việc với Firefox

Response.Write("Processing..."); 
Response.Flush(); 
System.Threading.Thread.Sleep(5000); 
Response.Write("Finish"); 
Response.End(); 

Trong Firefox nó hoạt động như mong đợi nhưng trong IE8, Safari và Chrome nó chờ đợi cho đến khi tất cả mã được xử lý và sau đó hiển thị toàn bộ văn bản.

Tôi đã cố gắng gửi một HTML hình thành tốt hơn giống như các mẫu dưới đây nhưng tôi nhận được kết quả tương tự:

Response.Write("<html><head><title>test</title></head><body>Processing...</body></html>"); 
Response.Flush(); 
System.Threading.Thread.Sleep(5000); 
Response.Write("Finish"); 
Response.End(); 

Cảm ơn bạn!

Trả lời

2

Sự cố bạn đang gặp phải là phản hồi bạn đang gửi vẫn chưa hoàn tất. Mặc dù bạn tuôn ra bất cứ thứ gì nằm trong bộ đệm cho trình duyệt, nó vẫn cho phép trình duyệt chờ kết thúc phản hồi hoặc xử lý những gì nó có cho đến nay - do đó sự khác biệt giữa các trình duyệt.

Điều thậm chí còn tệ hơn là bạn có thể mong đợi hành vi tương tự từ một số bộ tập trung trung gian, tường lửa, v.v. trên internet giữa máy chủ và trình duyệt của bạn.

Điểm mấu chốt là nếu bạn muốn đảm bảo rằng trình duyệt làm điều gì đó với luồng dữ liệu của bạn, bạn phải hoàn thành nó với Response.End.

Nói cách khác, nếu bạn muốn gửi một số dữ liệu trả lời của bạn đầu tiên và sự chậm trễ gửi phần còn lại lựa chọn tốt hơn của bạn là phá vỡ các phản ứng trong hai, hoàn thành đầu tiên và tải về phần thứ hai riêng

+0

Vì vậy, AJAX là cách duy nhất để làm điều đó? –

+0

Bạn có thể chơi một số thủ thuật khác - IFrame là một, nhưng ajax là phần mềm hoàn hảo nhất và với các khung công tác như JQuery, nó không phải là một thách thức để thực hiện – mfeingold

3

Một cách dễ dàng cách để giải quyết vấn đề này là đặt trang "Vui lòng chờ, xử lý" ở phía trước trang thực sự thực hiện công việc. Thông báo "vui lòng đợi" được hiển thị và sau đó nó bắt đầu xử lý ngay lập tức bằng cách sử dụng thẻ làm mới meta và/hoặc javascript để chuyển hướng đến trang xử lý thực tế.

"Please Wait" Page:

<html> 
<head> 
    <meta http-equiv="refresh" content="0;url=process.aspx?option1=value&...." /> 
    <title>Please Wait, Processing</title> 
</head> 
<body> 
    Processing... 
</body> 
<script type="text/javascript"> 
    window.location = "process.aspx?option1=value&...."; 
</script> 
</html> 

Ghi chú:

  1. Sử dụng hai phương pháp để khởi động chế biến được thực hiện để đảm bảo nếu một trình duyệt không thể sử dụng một, nó sẽ hy vọng sử dụng phương pháp khác.
  2. Bạn sẽ phải thay thế url xử lý và chuỗi truy vấn cho phù hợp.
  3. Một nhược điểm của phương pháp này là nếu người dùng nhấn nút quay lại trình duyệt, họ sẽ quay lại trang "vui lòng đợi" từ trang "quy trình", nghĩa là nó sẽ vô tình khởi động lại công việc. Tôi sẽ để lại thử thách đó cho một chủ đề khác!
+0

Tuyệt vời! dễ dàng và đơn giản ... Tôi chỉ upvoted câu trả lời của bạn bởi vì câu hỏi là lý do tại sao Flush() đã không làm việc, nhưng câu trả lời của bạn đã giúp tôi rất nhiều. Cảm ơn! –

+0

Cảm ơn =) Khi mfeingold cho biết, phản hồi đang bị xóa, vấn đề nằm ở trình duyệt, khi họ quyết định khi nào họ sẽ hiển thị những gì đã được nhận cho đến thời điểm này. Do đó ý tưởng của tôi, đảm bảo toàn bộ trang Vui lòng đợi và được hiển thị trước khi bắt đầu xử lý. Niềm vui của lập trình web! – Will

2

Khi bạn gọi Response.Flush() trước khi phản ứng hoàn tất (trước Content-Length được biết đến), thời gian chạy ASP.NET tạo ra một phản ứng một phần chunked mã hóa. Nó tùy thuộc vào trình duyệt để quyết định cách render nó. Trong thử nghiệm của tôi, tôi thấy rằng các trình duyệt có xu hướng hiển thị hình ảnh (<img> thẻ) được bao gồm trong phản hồi một phần. Bạn có thể thử điều đó.

Tuy nhiên, hãy cẩn thận khi gửi </html> quá sớm; các trình duyệt có thể bỏ qua bất kỳ điều gì trong quá khứ. Tuy nhiên, các trình duyệt sẽ hiển thị từng phần một phần - vì vậy bạn có thể bắt đầu với phần đầu trang của mình như thường lệ.

Trong trường hợp hữu ích, tôi xem qua một ví dụ cụ thể trong cuốn sách của tôi, bao gồm dấu vết gói cho biết chính xác những gì xảy ra trên dây: Ultra-Fast ASP.NET.

+0

Shameless plug. +1. –

3

Ngoài ra, lưu ý rằng nếu máy chủ IIS của bạn đang nén đầu ra bằng GZIP, thì dường như nó sẽ bỏ qua tất cả các cuộc gọi Response.Flush.

này được bật theo mặc định trong IIS7 và trên Windows 7.

Và, nếu bạn đang thử nghiệm với Fiddler, hãy chắc chắn để bật chế độ "Trực tuyến", hoặc Fiddler sẽ thu thập HTML ửng đỏ và giữ nó cho đến khi kết nối hoàn tất.

0

Tôi nghĩ rằng trình duyệt nhận và sử dụng nội dung dựa trên độ dài của nó, vì vậy bạn có thể thử đệm 1000 ký tự hoặc hơn. Ví dụ:

chuỗi myVeryShortMessage = "Processing ...";

Response.Write (myVeryShortMessage.PadRight (1000)); Response.Flush();

System.Threading.Thread.Sleep (5000);

Response.Write ("Finish" .PadRight (1000)); Response.Flush();

Các vấn đề liên quan