Вопрос

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

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();

Спасибо!

Это было полезно?

Решение

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

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

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

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

Другие советы

Простой способ решить эту проблему - разместить страницу "Пожалуйста, подождите, обработка" перед фактической страницей, которая выполняет эту работу.Отображается сообщение "пожалуйста, подождите", после чего оно немедленно начинает обработку с использованием мета-тега обновления и / или 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. Одним из недостатков этого метода является то, что если пользователь нажмет кнопку возврата браузера, он вернется на страницу "пожалуйста, подождите" со страницы "процесс", что означает, что задание снова будет случайно запущено.Я оставлю этот вызов для другой темы!

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

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

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

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

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

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

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

строка myVeryShortMessage = "Обработка...";

Ответ.Написать (myVeryShortMessage.PadRight(1000));Ответ.Промывка ();

Система.Нарезание потоков.Нитки.Сон (5000);

Ответ.Написать("Готово".Заполнение (1000));Ответ.Промывка ();

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top