TPL DataFlow не обрабатывает все сообщения - PullRequest
0 голосов
/ 16 мая 2018

Я реализую простой загрузчик данных через HTTP, следуя советам из моего предыдущего вопроса C # .NET Операция параллельного ввода-вывода (с регулированием) , на которую отвечает Регулирование асинхронных задач .

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

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

Мой метод выглядит следующим образом (без обработки ошибок):

    public async Task<IEnumerable<DummyData>> LoadAsync(IEnumerable<Uri> uris)
    {
        IList<DummyData> result;
        using (var client = new HttpClient())
        {
            var buffer = new BufferBlock<DummyData>();

            var downloader = new TransformBlock<Uri, string>(
                async u => await client.GetStringAsync(u),
                new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = _maxParallelism });

            var deserializer =
                new TransformBlock<string, DummyData>(
                    s => JsonConvert.DeserializeObject<DummyData>(s),
                    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });

            var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };

            downloader.LinkTo(deserializer, linkOptions);
            deserializer.LinkTo(buffer, linkOptions);

            foreach (Uri uri in uris)
            {
                await downloader.SendAsync(uri);
            }

            downloader.Complete();
            await downloader.Completion;

            buffer.TryReceiveAll(out result);
        }

        return result;
    }

Если говорить точнее, у меня есть 100 URL для загрузки, но я получаю 90-99 ответов. Нет ошибок и сервер обработал 100 запросов. Это происходит случайным образом, большая часть кода времени ведет себя правильно.

...