Ссылка TransformBlock, создающая IEnumerable <T>, для блока, который получает T - PullRequest
0 голосов
/ 04 июня 2018

Я пишу скребок для веб-галереи и хочу как можно больше параллельно обрабатывать файлы с помощью TPL Dataflow.

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

Вот схема моей программы:

var galleryBlock = new TransformBlock<Uri, IEnumerable<Uri>>(async uri =>
{
    // 1. Get the page
    // 2. Parse the page to get the urls of each image page
    return imagePageLinks;
});

var imageBlock = new TransformBlock<Uri, Uri>(async uri =>
{
    // 1. Go to the url and fetch the image page html
    // 2. Parse the html to retrieve the image url
    return imageUri;
});

var downloadBlock = ActionBlock<Uri>(async uri =>
{
    // Download the image from uri to list
});

var opts = new DataflowLinkOptions { PropagateCompletion = true};
galleryBlock.LinkTo(imageBlock, opts); // this doesn't work, as I'm returning a list and not a single Item. However I want to progress that block in parallel.
imageBlock.LinkTo(downloadBlock, opts);

1 Ответ

0 голосов
/ 04 июня 2018

Вы можете использовать TransformManyBlock вместо вашего TransformBlock:

var galleryBlock = new TransformManyBlock<Uri, Uri>(async uri =>
{
    return Enumerable.Empty<Uri>(); //just to get it compiling
});

var imageBlock = new TransformBlock<Uri, Uri>(async uri =>
{
    return null;  //just to get it compiling
});

var opts = new DataflowLinkOptions { PropagateCompletion = true };
galleryBlock.LinkTo(imageBlock, opts); // bingo!
...