TPL DataFlow未执行

huangapple go评论62阅读模式
英文:

TPL DataFlow not executing

问题

我有以下的代码:

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}");
        }

    }
}

这段代码摘自这篇文章

然而,当我运行它时,只看到以下内容:

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

我也期望看到"Downloading {File}"==> UrlImage: {urlImage}的部分。

英文:

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

得分: 0

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.

英文:

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.

huangapple
  • 本文由 发表于 2023年3月3日 22:51:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628562.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定