Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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
Linq延迟执行_Linq_Linq To Objects_Deferred Execution - Fatal编程技术网

Linq延迟执行

Linq延迟执行,linq,linq-to-objects,deferred-execution,Linq,Linq To Objects,Deferred Execution,我写了一个简单的程序,下面是它的样子,隐藏了一些细节: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace routeaccounts { class Program { static void Main(string[] args) { //Draw

我写了一个简单的程序,下面是它的样子,隐藏了一些细节:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace routeaccounts
{
    class Program
    {
        static void Main(string[] args)
        {
            //Draw lines from source file
            var lines = File.ReadAllLines("accounts.txt").Select(p => p.Split('\t'));
            //Convert lines into accounts
            var accounts = lines.Select(p => new Account(p[0], p[1], p[2], p[3]));
            //Submit accounts to router
            var results = accounts.Select(p => RouteAccount(p));
            //Write results list to target file
            WriteResults("results.txt", results);
        }

        private static void WriteResults(string filename, IEnumerable<Result> results)
        {
            ... disk write call ...
        }

        private static Result RouteAccount(Account account)
        {
            ... service call ...
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
命名空间路由计数
{
班级计划
{
静态void Main(字符串[]参数)
{
//从源文件中绘制线
var lines=File.ReadAllLines(“accounts.txt”).Select(p=>p.Split('\t'));
//将行转换为帐户
var账户=行。选择(p=>新账户(p[0],p[1],p[2],p[3]);
//向路由器提交帐户
var结果=账户。选择(p=>RouteAccount(p));
//将结果列表写入目标文件
WriterResults(“results.txt”,results);
}
私有静态void WriteResults(字符串文件名、IEnumerable结果)
{
…磁盘写入调用。。。
}
私有静态结果RouteAccount(帐户)
{
…服务电话。。。
}
}
}
我的问题是——显然,当从数据上下文中选择时,执行会延迟。如果您注意到,在“Main”函数的第一条语句中,我是从File.ReadAllLines(“accounts.txt”)查询的。这是一个错误的选择吗?如果我列举最后的结果,这句话会重复吗


如果我知道这是一个问题,我可以简单地使用.ToArray()或提前获取结果,但我很想知道幕后发生了什么。

最好使用.NET 4.0中的
File.ReadLines
来延迟读取文件。现在,文件的读取不会延迟,当
file.ReadAllLines
返回时,会将整个文件读取到内存中。这只会发生一次。

不会重复读取文件,不会-因为执行的这一部分不会延迟。它将返回一个数组,然后调用
Select
将返回一个序列。。。投影将被延迟,但文件的读取不会延迟。该数组将保留在内存中,直到(直接或间接)引用它的所有内容都符合垃圾收集条件。。。它不需要重新读取该文件

另一方面,您可能希望使用
ToList()
或类似的方法读取结果,因为这样,您就可以在开始编写结果之前找出任何错误。在开始执行带有副作用的代码之前(我想,
WriteResults
会产生副作用),确保您已经获得了所需的所有数据通常是一个好主意。很明显,就每次内存中需要的数据量而言,它的效率较低。。。这是一个天平,您必须自己称重。

//文件现在读取,但稍后拆分。
        //File is read now, but split later.
        var lines = File.ReadAllLines("accounts.txt").Select(p => p.Split('\t')); 
        //Accounts are new'd up later.
        var accounts = lines.Select(p => new Account(p[0], p[1], p[2], p[3])); 
        //Accounts are Routed later.
        var results = accounts.Select(p => RouteAccount(p)); 
        //Write results list to target file 
        WriteResults("results.txt", results);

    private static void WriteResults(string filename, IEnumerable<Result> results)   
    {   
        //file is split, accounts are new'd up and routed by enumerating results
        List<Result> items = results.ToList();
    }   
var lines=File.ReadAllLines(“accounts.txt”).Select(p=>p.Split('\t')); //以后会有新的账户。 var账户=行。选择(p=>新账户(p[0],p[1],p[2],p[3]); //账户将在稍后发送。 var结果=账户。选择(p=>RouteAccount(p)); //将结果列表写入目标文件 WriterResults(“results.txt”,results); 私有静态void WriteResults(字符串文件名、IEnumerable结果) { //文件被拆分,帐户被新建,并通过枚举结果进行路由 列表项=results.ToList(); }
谢谢你的回答,但是你能告诉我是如何决定是否延期的吗?这将是有益的information@Eugarps当前位置没有规则。可以看出,
File.ReadAllLines
不会延迟,因为它返回一个数组。但是仅仅因为一个方法返回
IEnumerable
,并不意味着它被延迟(它返回的具体对象可以是,比如说,一个
列表
)。方法返回
IEnumerable
是一个提示,它可能会被延迟,但不是一个保证。此外,延迟执行和延迟执行之间有着巨大的区别(想想看
Enumerable.OrderBy
,它是延迟的,但不是延迟的)。我被分为你的答案和Jon的答案,但我投票支持他,因为这是最先发生的。在您的回复中,特别有用的是引用了ReadLines,我不知道这一点,但非常符合我的目的。这是一个很好的建议,我在LINQ中遇到了一些问题,延迟执行实际上导致异常被抛出到我不希望处理它们的地方。