有人能讲解一下Linq中的并行计算在“TakeWhile”时的机制吗。。

phommy 2014-06-20 02:23:49
看到 ParallelQuery<> 有个扩展方法 TakeWhile<>,想不通它的机制是如何的

比如一个序列:
Enumerable.Range(1,100).AsParallel().Select( i=> {这里是一个复杂操作; return i;} )

我对它 TakeWhile(m => m < 10) 的时候碰巧9、10、11三个数同时在计算,结果10先跑到了TakeWhile,那9和11还会输出吗?
我当然希望输出9、不输出11;但对于11的那个“复杂操作”已经在计算中了,那个线程会被强行中止吗?还是说那个线程顺利执行完、但返回的数据(11)被舍弃掉了?再或者说这个TakeWhile返回的序列中就包括这个11呢?


最后,当我对别人给我的一个 IEnumerable 做TakeWhile时,是不是要判断它是否为 ParallelQuery 呢?
...全文
144 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
游离失所 2014-06-23
  • 打赏
  • 举报
回复
至于你发贴的那个问题。只要自己实际测试一次就知道了。。 我觉得我上面说的那个概念非常重要,也是很多人不注意的,所以导致很多人说linq速度慢。。因为他们没有把查询结果tolist 加载到内存当中。。当他们重复使用变量a的时候,而是又是执行一次查询,然后得到结果。。
游离失所 2014-06-23
  • 打赏
  • 举报
回复
这就是你那里会停顿1秒的原因
游离失所 2014-06-23
  • 打赏
  • 举报
回复
这个很简单。。其实.AsParallel()这部就是把上面要执行的那些东西已经执行完了,并且加载到内存当中。。这个跟AsEnumable()性质一样。。 无论linq还是plinq都有一个重要的知识点,那就是延迟加载。 var a= Enumerable.Range(1, 100).AsParallel().Select(m => { Console.WriteLine("Selecting " + m); //Thread.Sleep(20 * m); return m; }).TakeWhile(m => { Console.WriteLine("Taking " + m); return m < 10; }) 这里的a相当一个游标。。当你对a进行操作时才会去执行查询。。哪怕你Enumerable.Range(1, 无限大),而且做非常复杂的操作,这一步也是瞬间过。。 当你toList() AsParallel() AsEnumable() 其实就是把它执行了,并且加载在内存当中
phommy 2014-06-23
  • 打赏
  • 举报
回复
顶一下。。4楼问题纯属分支,真正想弄明白的还是plinq对takewhile的处理。。
phommy 2014-06-20
  • 打赏
  • 举报
回复
引用 2 楼 Z65443344 的回复:
自己跑一下代码试试不就知道了
实际跑代码发现更奇怪的事了,带注释的那行 AsParallel 会使原本瞬间完成的代码效率低降低几个数量级。。。为什么会这样呢。。当然这一行完全没有必要,只是想知道原理。。。

using System;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Enumerable.Range(1, 100).AsParallel().Select(m =>
            {
                Console.WriteLine("Selecting " + m);
                //Thread.Sleep(20 * m);
                return m;
            }).TakeWhile(m =>
            {
                Console.WriteLine("Taking " + m);
                return m < 10;
            })
            .AsParallel()   //加这一行后,运行到m==10后,每次输出有1秒钟奇怪的停顿,为什么呢
            .ForAll(Console.WriteLine);
            Console.Read();
        }
    }
}
phommy 2014-06-20
  • 打赏
  • 举报
回复
引用 1 楼 duanzi_peng 的回复:
谁有时间在这给你讲解,自己查资料吧。 http://social.msdn.microsoft.com/Search/zh-CN?query=TakeWhile&emptyWatermark=true&ac=4
引用 1 楼 duanzi_peng 的回复:
谁有时间在这给你讲解,自己查资料吧。 http://social.msdn.microsoft.com/Search/zh-CN?query=TakeWhile&emptyWatermark=true&ac=4
这里只是教科书式的罗列接口而已。。尤其是搜索条件加上 ParallelQuery 之后。请相信我也是做过功课后才来提问的 如果没有时间详细说明,能否只回答我的最终问题: “当我对别人给我的一个 IEnumerable 做TakeWhile时,是不是要判断它是否为 ParallelQuery 呢?”
於黾 2014-06-20
  • 打赏
  • 举报
回复
自己跑一下代码试试不就知道了
exception92 2014-06-20
  • 打赏
  • 举报
回复

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧