Продолжить после исключения в C # - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь получить типы документов ок.3к ссылок.Но я всегда получаю исключение, когда оно достигает отметки 700-900.

Как я могу продолжить в том месте, где произошло исключение (поэтому я не обязан начинать с нуля еще раз)?Это вообще возможно?

Вот код, который я использовал:

     try
        {
            Parallel.ForEach(linkList, link => 
            {
                stopwatch.Restart();
                Console.Write($"Downloading page {index++} of {linkList.Count}...");
                documents.Add(LoadPage(link));
                Console.Write($" in {stopwatch.Elapsed.TotalMilliseconds} ms");
                Console.WriteLine();
            });

            return documents;
        }
        catch (Exception e)
        {
            ???
        }

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Вам просто нужно обработать их в ForEach

Parallel.ForEach(linkList, link => 
{
    try
    {
       ...
     }
     catch(Exception ex)
     {
        // log
     }
});

Однако у вас есть больше проблем, чем это.

  1. это похоже на IO-связанную рабочую нагрузку, котораяне подходит для Parallel.ForEach
  2. documents.Add не выглядит потокобезопасным
  3. ваш индекс будет отсутствовать

Честно говоря, это действительно похоже на работу для TPL Dataflow , он дает вам преимущество хорошей работы с асинхронными и ожидающими и связанными с IO рабочими нагрузками.использование async и await перестанет сбивать планировщик задач, позволяя портам завершения ввода-вывода выполнять свою работу, освобождая пул потоков.

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

0 голосов
/ 26 февраля 2019

Ладно, ребята, вот решение, которое привело меня к моей цели.

        var index = 1;
        Parallel.ForEach(linkList,  link => { GetDocuments(stopwatch, index++, linkList, documents, link); });

        if (FailedDownloads.Count > 0)
        {
            linkList = new List<string>(FailedDownloads);
            FailedDownloads.Clear();
            Parallel.ForEach(linkList,
                link => { GetDocuments(stopwatch, index++, linkList, documents, link); });
        }
        return documents;
    }

    private void GetDocuments(Stopwatch stopwatch, int index, List<string> linkList, List<HtmlDocument> documents, string link)
    {
        stopwatch.Restart();
        Console.Write($"Downloading page {index} of {linkList.Count}...");
        try
        {
            documents.Add(LoadPage(link));
            Console.Write($" in {stopwatch.Elapsed.TotalMilliseconds} ms");
        }
        catch (AggregateException e)
        {
            if (e.InnerExceptions[0] is HttpRequestException)
            {
                FailedDownloads.Add(link);
                Console.WriteLine(e);
            }
            else
            {
                throw;
            }
        }
0 голосов
/ 26 февраля 2019

Попробуйте обернуть внутренний код в try-catch

        Parallel.ForEach(linkList, link => 
        {
            try
            {
                stopwatch.Restart();
                Console.Write($"Downloading page {index++} of {linkList.Count}...");
                documents.Add(LoadPage(link));
                Console.Write($" in {stopwatch.Elapsed.TotalMilliseconds} ms");
                Console.WriteLine();
            }
            catch (Exception e)
            {
                ???
            }
        });

        return documents;

РЕДАКТИРОВАТЬ:

Вы также можете посмотреть многопоточных коллекций , которые есть в C #предлагать как обычные коллекции не поточнобезопасные

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