Response.Flush () работает только с Firefox - PullRequest
5 голосов
/ 28 ноября 2009

Я пытаюсь отправить некоторый контент клиенту, прежде чем выполнять какую-то долгую работу:

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

В Firefox он работает, как и ожидалось, но в IE8, Safari и Chrome ждет, пока не будет обработан весь код, а затем показывает весь текст.

Я попытался отправить лучше сформированный HTML, как показано ниже, но получаю те же результаты:

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

Спасибо!

Ответы [ 5 ]

3 голосов
/ 20 апреля 2010

Также имейте в виду, что если ваш IIS-сервер сжимает выходные данные с помощью GZIP, то он, похоже, игнорирует все Response.Flush вызовы.

Это включено по умолчанию в IIS7 и в Windows 7.

И, если вы тестируете с Fiddler, обязательно включите режим «Потоковое», иначе Fiddler соберет очищенный HTML-код и удерживает его до тех пор, пока не будет установлено соединение.

3 голосов
/ 28 ноября 2009

Простой способ решить эту проблему - разместить страницу «Пожалуйста, подождите, обработка» перед фактической страницей, которая выполняет эту работу. Появится сообщение «Пожалуйста, подождите», после чего оно немедленно начнет обработку, используя мета-тег обновления и / или JavaScript для перенаправления на страницу фактической обработки.

Страница "Пожалуйста, подождите":

<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>

Примечания:

  1. Использование двух методов для запуска обработки выполняется, чтобы гарантировать, что если браузер не может использовать один из них, мы надеемся, что он будет использовать другой метод.
  2. Вам придется заменить URL-адрес обработки и строку запроса на подходящий.
  3. Одним из недостатков этого метода является то, что если пользователь нажмет кнопку «Назад» в браузере, он вернется на страницу «Пожалуйста, подождите» со страницы «Процесс», что означает, что он случайно запустит задание снова. Я оставлю этот вызов в другой теме!
2 голосов
/ 28 ноября 2009

Когда вы вызываете Response.Flush () до того, как ответ будет завершен (до того, как станет известен Content-Length), среда выполнения ASP.NET генерирует частичный ответ с кодированием по частям. Это зависит от браузера, чтобы решить, как это сделать. В моем тестировании я обнаружил, что браузеры имеют тенденцию отображать изображения (теги <img>), которые включены в частичный ответ. Вы можете попробовать.

Однако будьте осторожны с отправкой </html> слишком рано; браузеры могут игнорировать что-либо за пределами этой точки. Однако браузеры отображают неполные страницы все время, так что вы можете начать с начала своей страницы, как обычно.

В случае, если это полезно, я подробно рассмотрю пример этого в своей книге, включая трассировку пакетов, которая точно показывает, что происходит на проводе: Сверхбыстрый ASP.NET .

2 голосов
/ 28 ноября 2009

Проблема, с которой вы сталкиваетесь, заключается в том, что отправляемый вами ответ все еще неполон. Даже если вы сбросите все, что находится в буферах, в браузер, браузер все равно должен дождаться окончания ответа или обработать то, что он получил до сих пор - отсюда и разница между браузерами.

Что еще хуже, вы можете ожидать того же поведения от некоторых концентраторов промежуточных узлов, брандмауэров и т. Д., Расположенных в Интернете между вашим сервером и браузером.

Суть в том, что если вы хотите убедиться, что браузер что-то делает с вашим потоком данных, вы должны заполнить его Response.End.

Другими словами, если вы хотите сначала отправить некоторые из ваших данных ответа и отложить отправку остальных, вам лучше разбить ответ на два, завершить первый и загрузить вторую часть отдельно

0 голосов
/ 18 января 2011

Я думаю, что браузеры получают и используют контент в зависимости от его длины, поэтому вы можете попробовать заполнить 1000 символов или около того. Например:

string myVeryShortMessage = "Processing ...";

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

System.Threading.Thread.Sleep (5000);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...