Как я могу узнать на стороне клиента, когда обработчик HTTP завершит обработку?
-
02-07-2019 - |
Вопрос
Вероятно, длинный вопрос для простого решения, но вот...
У меня есть специальный элемент управления Silverlight для выбора нескольких файлов и отправки их на сервер.Он отправляет файлы общему обработчику (FileReciever.ashx), используя метод OpenWriteAsync элемента управления WebCLient.
По сути, код silverlight делает что-то подобное для каждого файла:
WebClient client = new WebClient();
client.OpenWriteCompleted += (sender, e) =>
{
PushData(data, e.Result);
e.Result.Close();
data.Close();
};
client.OpenWriteAsync(handlerUri);
Обработчик на стороне сервера просто считывает входящий поток, а затем выполняет дополнительную обработку полученного массива байтов.
ПРОБЛЕМА заключается в том, что OpenWriteCompleted на стороне клиента выполняется, как только все данные передаются по сети.Мой код продолжит работу со следующим файлом.Чего я действительно хочу, так это дождаться, пока обработчик ASHX завершит всю обработку этого запроса.Как мне это сделать?Какой-нибудь механизм ожидания в WebClient?Какой обратный вызов я могу выполнить для HttpContext в обработчике?Должен ли я использовать какой-то другой метод передачи?Пожалуйста посоветуй!
Решение
Хм, может быть, простым решением может быть пометка URL-адреса GUID (GUID уникален для каждого файла или передачи, в зависимости от того, что имеет смысл в вашей ситуации).Затем вы можете иметь еще один простой веб-сервис, способный проверять состояние другого сервиса на основе guid, и ваш клиент Silverlight запрашивает у этого нового сервиса статус его обработки (путем передачи новому веб-сервису guid прошлый трансфер).
Другие советы
Тот же вопрос был задан в Silverlight форумы.Ответ, одобренный Microsoft, заключался в том, что вы не можете сделать это с помощью WebClient и OpenWriteAsync.Вам понадобится либо пользователь UploadStringAsync, либо HttpWebRequest.
Я предполагаю, что вы обеспокоены тем, что передача данных, возвращаемых обработчиком, занимает много времени, а сервер в это время не используется.Невозможно определить, когда сервер завершил обработку, поэтому я не думаю, что вы сможете сделать это без изменения своей архитектуры.
Я бы хотел, чтобы ваш обработчик имел только какой-то идентификатор (например, GUID или int), который можно использовать для получения результата обработчика в другом запросе.Таким образом, страница вызовет обработчик, обработчик сохранит результат и вернет идентификатор, страница вызовет обработчик во второй раз и вызовет другой обработчик, чтобы получить результат первого вызова.Это позволит использовать ваш сервер во время передачи данных.
Или вы, вероятно, можете сделать это с помощью JavaScript (jQuery)...если вы не против использовать JavaScript.
Если файлы не очень большие и каждый из них можно хранить в памяти, некрасивое, но эффективное решение — преобразовать их в строки и отправить с помощью метода UploadStringAsync.
Избегайте этого подхода, если размер файла неограничен, но если вы можете теперь, когда они будут относительно небольшими, можно использовать этот подход.