2013-04-07 97 views
2

我正在研究TPL Dataflow。 Belwo是官方文档Stephen Toub. Introduction to TPL Dataflow (TPLDataflow.docx)中的两段代码片段。但是我没有完全弄清楚它们之间的区别。TPL Dataflow:这两个代码片段有什么区别?

顺便说一句,这两个代码片段是文档中的样本,用于演示目的。他们不完整。

  1. 下载图像依次同步方式

    var downloader = new ActionBlock<string>(url => 
    { 
        // Download returns byte[] 
        byte [] imageData = Download(url); 
        Process(imageData); 
    }); 
    
    downloader.Post("http://msdn.com/concurrency"); 
    downloader.Post("http://blogs.msdn.com/pfxteam"); 
    
  2. 下载图像依次异步

    var downloader = new ActionBlock<string>(async url => 
    { 
        byte [] imageData = await DownloadAsync(url); 
        Process(imageData); 
    }); 
    
    downloader.Post("http://msdn.com/concurrency "); 
    downloader.Post("http://blogs.msdn.com/pfxteam"); 
    
+0

当然我知道。但我需要一些详细的解释。因为当我尝试时,输出看起来没有什么不同。 – smwikipedia 2013-04-07 11:12:47

+0

以下是来自MSDN论坛的相关答案。 http://social.msdn.microsoft.com/Forums/en-US/tpldataflow/thread/1afcff27-eb13-4b0b-92de-4ce067874e47 – smwikipedia 2013-04-09 01:21:49

回答

6

在你的第一个例子中,每个PIEC e发布的数据,ActionBlock会将其委托列入线程池。 Download将阻塞一个线程池线程,然后在同一个线程池线程上执行Process

在第二个示例中,对于发布的每条数据,ActionBlock将其委托排队到线程池。 await将异步等待下载,因此线程池线程将在下载期间返回到线程池。当下载完成时,方法的其余部分排队到线程池,Process将在线程池线程上执行。

所以在一般情况下,第二个例子更有效率。

您可能会发现我的async/await intro有帮助。

+0

谢谢斯蒂芬。在我的第一个示例中,尽管第一个发布的数据可能会阻塞线程池线程,但我认为第二个发布的数据仍然可以在另一个线程池线程上运行。所以这里涉及2个线程池线程。在我的第二个例子中,第一个线程池线程可以返回到线程池。所以第二个线程池线程可能不是必需的。所以可能只涉及1个线程池。我希望我明确自己。但这是正确的吗? – smwikipedia 2013-04-07 14:42:37

+0

我刚刚阅读了你对James的评论,所以如果我设置* MaxDegreeOfParallelism = 2 *,则可能涉及2个线程池线程。 – smwikipedia 2013-04-07 14:45:52

+0

@smwikipedia是的,但同步代码会在它下载的整个时间内阻塞两个线程。另一方面,异步代码只会在短时间内使用两个线程(一次是在开始时,一次是在下载结束时),或者它可以在同一个线程上执行(同时保持并行下载)。 – svick 2013-04-07 18:01:34