TPL DataFlow not executing

39 views Asked by At

I have the following code:

using System;
using System.Net;
using System.Threading.Tasks.Dataflow;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        var fetchImageFlag = new TransformBlock<string, (string, byte[])>(
            async urlImage => {
                Console.WriteLine($"Downloading {urlImage}");
                using var webClient = new WebClient();
                var data = await webClient.DownloadDataTaskAsync(urlImage); 
                return (urlImage, data);
            });

        var saveData = new ActionBlock<(string, byte[])>(data => { 
            (string urlImage, byte[] image) = data;
            Console.WriteLine($"==> UrlImage: {urlImage}");
        });

        fetchImageFlag.LinkTo(saveData); 

        List<string> urlFlags = new List<string>{
            "Italy#/media/File:Flag_of_Italy.svg",
            "Spain#/media/File:Flag_of_Spain.svg",
            "United_States#/media/File:Flag_of_the_United_States.svg"
        };

        foreach (var urlFlag in urlFlags)
        {
            Console.WriteLine($"Calling: {urlFlag}");
            fetchImageFlag.Post($"https://en.wikipedia.org/wiki/{urlFlag}");
        }

    }
}

which is taken from this post.

However, when I run it, I only get:

Calling: Italy#/media/File:Flag_of_Italy.svg
Calling: Spain#/media/File:Flag_of_Spain.svg
Calling: United_States#/media/File:Flag_of_the_United_States.svg

I was also expecting to see the "Downloading {File}" and ==> UrlImage: {urlImage} parts.

1

There are 1 answers

2
Alberto On BEST ANSWER

You should call the Complete method on fetchImageFlag after posting all the messages and wait for Completion on the last block saveData. Otherwise your application just terminates before any actual job starts or completes. Also make sure to set PropagateCompletion=true on the Link method call.

public static void Main()
{
    ....

    fetchImageFlag.LinkTo(saveData, new DataflowLinkOptions { PropagateCompletion = true});
    ....

    foreach (var urlFlag in urlFlags)
    {
        Console.WriteLine($"Calling: {urlFlag}");
        fetchImageFlag.Post($"https://en.wikipedia.org/wiki/{urlFlag}");
    }

    fetchImageFlag.Complete();
    saveData.Completion.Wait();
}

Also note that the Console.WriteLine("Downloading {File}", urlImage); is invalid and should be: Console.WriteLine($"Downloading {urlImage}"); instead.