Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用PLINQ实现延迟加载?_C#_Lazy Loading_Plinq - Fatal编程技术网

C# 如何使用PLINQ实现延迟加载?

C# 如何使用PLINQ实现延迟加载?,c#,lazy-loading,plinq,C#,Lazy Loading,Plinq,linq的一个优点是可以根据请求延迟处理无限的数据源。我尝试并行化我的查询,发现延迟加载不起作用。例如 class Program { static void Main(string[] args) { var source = Generator(); var next = source.AsParallel().Select(i => ExpensiveCall(i)); foreach (var i in next)

linq的一个优点是可以根据请求延迟处理无限的数据源。我尝试并行化我的查询,发现延迟加载不起作用。例如

class Program
{
    static void Main(string[] args)
    {
        var source = Generator();
        var next = source.AsParallel().Select(i => ExpensiveCall(i));
        foreach (var i in next)
        {
            System.Console.WriteLine(i);
        }
    }

    public static IEnumerable<int> Generator()
    {
        int i = 0;
        while (true)
        {
            yield return i;
            i++;
        }
    }

    public static int ExpensiveCall(int arg)
    {
        System.Threading.Thread.Sleep(5000);
        return arg*arg;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
变量源=生成器();
var next=source.AsParallel().Select(i=>ExpensiveCall(i));
foreach(下一个中的变量i)
{
系统控制台写入线(一);
}
}
公共静态IEnumerable生成器()
{
int i=0;
while(true)
{
收益率i;
i++;
}
}
公共静态内部费用调用(内部参数)
{
系统线程线程睡眠(5000);
返回arg*arg;
}
}
这个程序无法产生任何结果,大概是因为在每一步中,它都在等待对生成器的所有调用停止,当然这永远不会发生。如果我打“Asparalle”电话,效果很好。那么,在使用PLINQ提高应用程序性能的同时,如何获得良好的延迟加载呢


我认为你混淆了两件不同的事情。这里的问题不是延迟加载(即只加载所需的量),这里的问题是输出缓冲(即不立即返回结果)

在你的情况下,你最终会得到你的结果,尽管这可能需要一段时间(对我来说,它需要大约500个结果才能返回第一批)。缓冲是出于性能原因而进行的,但在您的情况下,这没有意义。正如Ian正确指出的,您应该使用
.WithMergeOptions(ParallelMergeOptions.NotBuffered)
禁用输出缓冲


但是,据我所知,PLINQ不做延迟加载,也没有办法改变这一点。这意味着,如果您的消费者(在您的情况下,
foreach
循环)太慢,PLINQ将以超出必要的速度生成结果,并且仅当您完成迭代结果时才会停止。这意味着PLINQ可能会浪费CPU时间和内存。

非常好的一点。。。PLINQ中的缓冲只掩盖了没有延迟加载的问题。也许一种方法是使用一个扩展方法,对接下来的n个项进行批处理,并并行执行这些项,然后返回结果。这可能会产生虚假的懒惰行为…@tbischel是的,类似的事情会奏效。另一个选项是使用
BlockingCollection
BoundedCapacity
设置。
 var next = source.AsParallel()
              .WithMergeOptions(ParallelMergeOptions.NotBuffered)
              .Select(i => ExpensiveCall(i));