Как новичок в C#, как мне повторить функцию WebClient.DownloadString?

Я АБСОЛЮТНЫЙ НУБ C#, так что это мой самый первый проект. Я пишу программу командной строки C%, ввожу URL-адрес, который загружает изображения с веб-сайта галереи, который я часто посещаю. 99% написанного мной кода работает. Моя единственная проблема - это иногда мой код: при попытке получить исходный код веб-страницы иногда загрузка не удалась. 99% того, что я делаю, работает. Этот 1% иногда приводит к сбою моей программы. Я пытаюсь найти способ заставить WebClient.DownloadString повторить попытку загрузки источника страницы в случае ошибки. Несмотря на все вышесказанное, 99% кода написано и работает, поэтому я не буду переписывать его с нуля в другой версии .net. (Предложение, которое я видел на канале разногласий, посвященном кодированию на C#, не помогло ни в малейшей степени)

Это код, который у меня есть для загрузки исходного кода страницы:

static string getPageSource(string url)
{
  string pageSource = "";
  WebClient client = new WebClient();

  pageSource = client.DownloadString(url);
  if (pageSource.Length == 0)
    {
    pageSource = client.DownloadString(url);
    }
  return pageSource;
}

Сам код работает как есть. Просто всякий раз, когда это терпит неудачу, приложение вылетает.

Начните с того, что не используйте ЗАГЛАВНЫЕ буквы в названии вопроса, люди воспринимают это как КРИК и не читают дальше.

Solar Mike 06.08.2024 23:49

Пожалуйста, НЕ КРИЧИТЕ НА НАС...

Peter B 06.08.2024 23:50

Это похоже на проблему X/Y . Пожалуйста, прочитайте Как создать минимальный воспроизводимый пример. Мы не сможем помочь вам с аварийной программой, если вы не сообщите нам, где она дает сбой.

jwdonahue 06.08.2024 23:55

Очевидно, проблема в коде, который я опубликовал... Иногда, когда он пытается загрузить исходный код страницы, он терпит неудачу, и все приложение выходит из строя. Поэтому мне нужно найти способ сделать "pageSource = client.DownloadString(url);" повторите, если не получится.

YoItsTrev 07.08.2024 00:12

Единственное, что вы могли бы сделать, это реализовать некоторую обработку исключений . Посмотри, как ты с этим справишься. В качестве альтернативы есть пакет Polly, но для вашего сценария это может быть излишним.

Peppermintology 07.08.2024 00:22

@YoItsTrev «все приложение кэшируется» никоим образом не делает очевидным, что при этом методе происходит сбой. Как правило, приложения dotnet не «выходят из строя», они выдают исключения, и если они не обрабатываются должным образом, они закрываются более или менее контролируемым образом.

jwdonahue 07.08.2024 00:28

Обратите внимание, что немедленная повторная попытка не всегда является правильной реакцией на сбой. Этот веб-сайт может отклонять ваши запросы из-за того, что вы превысили лимит загрузки, или из-за того, что он в настоящее время перегружен, или из-за какой-либо промежуточной сетевой проблемы, которая может быть или не быть краткосрочным временным явлением.

jwdonahue 07.08.2024 00:35
WebClient одноразовый. Не забывайте выбрасывать его каждый раз, когда используете. Невыполнение этого требования может в конечном итоге привести к сбою.
Enigmativity 07.08.2024 00:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
8
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Первый шаг — всегда определять причину сбоя приложения. Для этого вы запускаете его в отладчике. В вашем случае, вероятно, выдается исключение в методе DownloadString, поэтому ваша вторая попытка никогда не вызывается.

Это всего лишь предположение, основанное на той ограниченной информации, которую вы предоставили. Судя по вашему посту, вы, видимо, новичок в программировании в целом, да? Вы, очевидно, еще не мыслите как программист, но этого следует ожидать от новичков.

Я рекомендую вам перейти по ссылкам в моем комментарии к вашему исходному сообщению и внимательно прочитать эти документы. Они помогут вам понять, как подходить к задаванию вопросов здесь. Что касается мышления программиста, всегда начинайте с внимательного чтения документации по API, который вы используете:

https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstring?view=net-8.0

Обратите внимание на список исключений:

Исключения ArgumentNullException Параметр адреса имеет значение null.

WebException URI, сформированный путем объединения BaseAddress и адреса, имеет вид неверный.

-или-

Произошла ошибка при загрузке ресурса.

NotSupportedException Метод был вызван одновременно несколько потоков.

В вашем случае, вероятно, выдается WebException из-за тайм-аута сервера или потому, что он запрещает вам доступ. Возможно, вы превышаете лимит загрузки.

Узнайте, как перехватывать исключения:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/Exception-handling-statements

Поместите свой код в блок try/catch:

    string getPageSource(string url)
    {
        var pageSource = string.Empty;

        try
        {
            using var client = new WebClient();
            pageSource = client.DownloadString(url);
        }
        catch(WebException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch(Exception ex)
        {
            Console.WriteLine($"Unexpeccted exception {ex.Message}");
        }

        return pageSource;
    }

Запустите это и сообщите нам, какое исключение было перехвачено, а затем я покажу вам, как правильно выполнить ограниченное количество повторов.


ПРИМЕЧАНИЕ. WebClient устарел и не должен использоваться. Если ваш инструктор советует вам использовать его, используйте его и заглушите его в комментариях о том, как хорошие программисты не будут его использовать и почему.

Я видел попытку в других сообщениях stackoverflow, но разве это не имеет значения? Да, он обработает ошибку, но не решит проблему. Он обработает ошибку, но не решит проблему повторной попытки загрузки исходного кода страницы.

YoItsTrev 07.08.2024 00:40

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

jwdonahue 07.08.2024 00:44

Я разместил ваш код в своем, но теперь он вылетает КАЖДЫЙ РАЗ, когда я его запускаю.

YoItsTrev 07.08.2024 00:48

«он вылетает КАЖДЫЙ РАЗ, когда я его запускаю» ни о чем нам не говорит. Выдает ли это исключение? Пожалуйста, опубликуйте весь текст исключения. Кроме того, я обновил блок кода, включив в него оператор using. Мне удалось его скомпилировать, но я не могу его протестировать, потому что вы никогда не публиковали минимальный воспроизводимый пример.

jwdonahue 07.08.2024 00:53

Если вы не видите вывод консоли из блоков catch, то, вероятно, там не возникает никаких исключений. Это значит, что он падает где-то еще, и нам нужно понять, где и почему.

jwdonahue 07.08.2024 00:58

Как вы запускаете этот код? Если вы запускаете его из IDE, возможно, окно консоли закрывается прежде, чем вы сможете прочитать какой-либо вывод. Попробуйте открыть оболочку cmd, перейти туда, где находится исполняемый файл, и запустить его вручную.

jwdonahue 07.08.2024 01:00

У меня ваш код работает. Выдавало ошибку 404. Мне пришлось прочитать одну строку кода, которую я не добавил в свой код выше: client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML) , как Gecko) Chrome/96.0.4664.93 Safari/537.36"); Я все еще получаю сообщение об ошибке, но оно сообщает слишком много запросов слишком быстро, поэтому я попробую сделать паузу.

YoItsTrev 07.08.2024 01:04

Итак, это была проблема X/Y. Вот почему те из нас, кто посидел здесь какое-то время, не принимают слова «он выходит из строя» за чистую монету. Вот почему вам нужно научиться вникать в проблему, прежде чем прийти сюда с просьбой о помощи. Пока вы не поймете фактическую ошибку, вы действительно не поймете, что не так. Повторная попытка тех же ошибочных процессов приведет к увеличению количества ошибок. Тем не менее, вы можете поместить весь этот блок try/catch в счетный цикл со встроенным вызовом Thread.Sleep(n), где n увеличивается при каждой последующей повторной попытке. Но вам все равно придется иметь дело с неудачами.

jwdonahue 07.08.2024 01:16

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

jwdonahue 07.08.2024 01:22

Ваша помощь и добавленная мной пауза не привели к сбоям при запуске программы десятки раз без проблем. Спасибо за нашу помощь, я очень ценю это.

YoItsTrev 07.08.2024 01:51

@YoItsTrev, спасибо. Не забудьте отметить эту тему как ответившую.

jwdonahue 07.08.2024 02:11

Используя код jwdonahue, я смог получить сообщение об ошибке. В сообщении говорилось, что он пытается получить доступ к серверу слишком быстро. После добавления паузы в код у меня не было сбоев.

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