我跟随 MSDN Walkthrough - Walkthrough: Creating a Dataflow Pipeline 。我创建了一个TransformBlock
并通过Post
执行它来执行它。
// Process "The Adventurous Life of a Versatile Artist: Houdini"
// by Harry Houdini.
downloadString.Post("http://www.gutenberg.org/cache/epub/45370/pg45370.txt");
然后,我调用Complete
方法并使用Console.WriteLine("Press a key to exit:");
行。
这里是完整的代码。您也可以在此阶段this commit on my github repo找到它。
using System;
using System.Net.Http;
using System.Threading.Tasks.Dataflow;
namespace Palindromes.ConsoleApp
{
class Program
{
static void Main(string[] args)
{
//
// Create members of the Pipeline
//
// Download the requested resource as a string
var downloadString = new TransformBlock<string, string>
( url =>
{
Console.WriteLine($"Downloading from {url}...");
string result = null;
using (var client = new HttpClient())
{
// Perform a synchronous call by calling .Result
var response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
// read result synchronously by calling .Result
result = responseContent.ReadAsStringAsync().Result;
if (!string.IsNullOrEmpty(result))
Console.WriteLine($"Downloaded {result.Length} characters...");
}
}
return result;
}
);
// Process "The Adventurous Life of a Versatile Artist: Houdini"
// by Harry Houdini.
downloadString.Post("http://www.gutenberg.org/cache/epub/45370/pg45370.txt");
downloadString.Complete();
Console.WriteLine("Press a key to exit:");
Console.ReadKey();
}
}
}
当我执行此控制台应用程序时,我希望看到输出如下。
Downloading from http://www.gutenberg.org/cache/epub/45370/pg45370.txt...
Downloaded 129393 characters...
Press a key to exit:
但这是实际输出。 (我已经多次运行它,并显示相同的Console.WriteLine
输出序列。
Press a key to exit:
Downloading from http://www.gutenberg.org/cache/epub/45370/pg45370.txt...
Downloaded 129393 characters...
为什么在调用Press a key to exit
TransformBlock
之前执行Console.WriteLine
行?
首先要调用TransformBlock
&#39; s Console.WriteLine
,因为我首先要调用它,因为这将成为管道的一部分?另外,据我所知,我没有任何async
代码,而且我不完全了解 TPL数据流的内部工作原理,为什么会这样做?似乎没有按顺序执行?
谢谢!
答案 0 :(得分:1)
为什么在按下TransformBlock的Console.WriteLines之前按一个键退出行执行?
Console.WriteLine("Press a key to exit:")
的调用发生在TransformBlock
完成转换功能之前。发布到TransfromBlock
的每个项目都将根据您的主要背景进行异步处理。
如果您想要等待管道完成,那么您需要阻止其Completion Task
或await
以async
方式完成:
private static async Task MainAsync() {
// Process "The Adventurous Life of a Versatile Artist: Houdini"
// by Harry Houdini.
downloadString.Post("http://www.gutenberg.org/cache/epub/45370/pg45370.txt");
downloadString.Complete();
await downloadString.Completion;
}
答案 1 :(得分:1)
Post
方法将在已发布项目存储在块的输入队列中后返回,它不会等待它被处理。
一旦目标块决定接受或拒绝该项,此方法将返回,但除非目标块的特殊语义另有规定,否则它不会等待实际处理该项。例如,一旦将已发布的项目存储到其输入队列中,ActionBlock将立即从Post返回。
然后异步处理输入队列中的项目。