日期:2014-05-20  浏览次数:20729 次

关于多线程编程和PLINQ的实例
好久没有发帖了。

我写了大量多线程程序,采用过各种手段来同步线程操作结果。实际上当不太要求非常高性能时,我们可以使用 PLINQ。因为它足够简单!

我举一个例子,假设我要访问csdn的.net论坛的首页列表,找出所有首页上的帖子中、有sp1234回帖(或者发帖)的,那么顺序依次查找每一个帖子,和并发查找帖子相比,慢多少呢?

大家可以自己做一个测试(使用 System.Diagnostics.Stopwatch)。我这里只是把测试代码写出来:

首先需要下载 Html Agility Pack,因为这里使用它分析 html 页面。在引用了它的dll并且在代码中using了它的命名空间之后,测试代码如下
var titles = from row in GetHtml("http://bbs.csdn.net/forums/DotNET/").DocumentNode.SelectSingleNode("//table[@class='table_list parent_forum ']").Elements("tr").Skip(1)
                let td = row.Element("td")
                where td != null
                let a = td.Descendants("a").FirstOrDefault()
                where a != null
                select new
                {
                    href = a.Attributes["href"].Value,
                    text = a.InnerText
                };
var pages = from t in titles.AsParallel().WithDegreeOfParallelism(64)
            where t.href != null
            let path = "http://bbs.csdn.net" + t.href
            let subQuery = from nick in GetHtml(path).DocumentNode.SelectNodes("//span[@class='name2nick']")
                            where nick.InnerText == "sp1234"
                            select nick
            where subQuery.Any()
            select new
            {
                title = t.text,
                href = path
            };
var results = pages.ToList();


当你将 
from t in titles.AsParallel().WithDegreeOfParallelism(64)
 改为简单的 
from t in titles
时,可以测试一下顺序执行需要多少时间。

我对c# 4.5的 Async 和Await 相当有意见,我认为它把非常简单和琐碎的事情给“搞砸了”,它使得许多程序员忘记了多线程编程的基本概念,因此应该尽量避免使用这两个让人“傻瓜化”的关键字。但是我对 PLINQ 如此强大和简单却非常敬佩,因为它不是针对简单和琐碎的事情,而是直接改变了非常复杂的编程工作,只有这个场景下才体现出“傻瓜化”的真正好处。