C # Надежная обработка сетевых подключений в ненадежных сетях

#c# #download #stream

#c# #Скачать #поток

Вопрос:

У меня есть довольно много фрагментов кода, которые корректно загружают x / html-страницы и файлы из Интернета, и они — по большей части — работают довольно хорошо.

К сожалению, мое домашнее интернет-соединение становится практически недоступным между полуночью и 6 утра. Я получаю много потерь пакетов и зависших соединений. Аналогично, у меня работает резервное 3G-соединение, которое периодически отключается в зависимости от нагрузки на сеть.

Конечно, я могу поместить код загрузки в try / catch — но в идеале я хотел бы, чтобы файл был правильно загружен, независимо от того, сколько времени это займет.

Я перепробовал несколько способов решения этой проблемы и добился смешанного успеха.

Я попытался получить длину потока, который я записываю, и убедиться, что моя локальная копия имеет ту же длину. По какой-то причине (правильно загруженная) локальная копия всегда казалась на несколько десятков байт короче заявленной длины потока, но фактическое число, на которое она была короче, казалось, различалось. Кроме того, не все потоки имеют доступную длину.

Я также попытался поместить свой сегмент try / catch’d в цикл for — заставив его попробовать загрузку, скажем, 50 раз. Успешная загрузка прервется, тогда как неудачная повторит попытку.

Я дополнил вышесказанное постепенно увеличивающейся задержкой — у меня был поток.Sleep(), который будет постепенно отключаться все дольше и дольше на каждой итерации, прежде чем пытаться снова.

Я полагаю, что эта задача не так проста, как кажется, поскольку многие мои персональные программы — Steam, Chrome, Центр обновления Windows, iTunes и т.д. … Похоже, вообще не справляются с моим ненадежным подключением. Мне часто приходится пытаться загрузить большие файлы 10-15 раз, прежде чем они будут успешно загружены. Либо эти разработчики не заботятся об обработке проблем с подключением, либо это сложно сделать.

Если это возможно, может кто-нибудь, пожалуйста, предоставить фрагмент кода, который будет захватывать поток из Интернета, но будет обрабатывать ненадежное соединение?

Я полагаю, это должно быть что-то вроде:

 public static MemoryStream Fetch(string url, int? maxRetries, int? maxDuration)
{
  // Download the response of the url to a MemoryStream.
  // Assume if null maxRetries and maxDuration, keep trying forever.
}
  

Ответ №1:

Я бы посоветовал изучить существующее решение. Мои первые две мысли заключаются в том, чтобы либо использовать BITS, либо перейти на Robocopy. Оба они хорошо проверены при загрузке файлов в потенциально нестабильных сетях (BITS — это то, что Центр обновления Windows использует для загрузки обновлений на ваш компьютер).