为什么ReadAllLines在WPF中工作,但在ConsoleApp中不工作

时间:2014-09-19 09:14:25

标签: c# csv file.readalllines

我正在对读取CSV文件的不同方法进行一些基准测试,并发现了一个“奇怪”的问题。问题是当我在控制台应用程序中使用此方法时:

        var lines = File.ReadAllLines(fileName); // OutOfMemoryException
        foreach (var line in lines)
        {
            //doing stuff
        }

我得到一个OutOfMemoryException,但是当我在WPF项目中使用相同的方法时,它工作正常。 我正在测试这个文件是730MB,我知道不要在更大的CSV文件上使用ReadAllLines,但为什么这个方法在WPF应用程序中有效但在控制台应用程序中却无效?

3 个答案:

答案 0 :(得分:5)

您正在使用32位进程并遭受地址空间碎片。这意味着运行时无法分配足够的连续内存,尽管总共可以释放足够的内存。 WPF可能只是有更好的内存布局。

将项目更改为64位。

或者,使用File.ReadLines流式传输文件。

答案 1 :(得分:3)

我怀疑你的WPF应用程序是在任何CPU上编译的,你在x32目标CPU上控制应用程序。如果在x64计算机上运行应用程序,则与x32编译的控制台应用程序(大约1.5 GB)相比,WPF应用程序可以使用更多内存。

另外我建议改变你的方法,如果可能的话,不要一次处理整个文件。

答案 2 :(得分:0)

我不会直接回答你的问题,但我认为指出OutOfMemoryException经常表明你的程序存在太大的记忆压力是非常重要的。 ,或者没有以非常好的方式使用可用资源。

在您的情况下,您通过调用File.ReadAllLines有效地将整个文件缓存在内存中。但是,这可能根本就没有必要,因为之后,您将逐行处理它。也就是说,在任何一个时刻只在内存中只有一行文本就足够了:

  • 正如this answer所述,您可以使用File.ReadLines逐行流式传输文件。

  • 如果您的目标是.NET 4之前的.NET Framework版本,那么该方法将无法使用。您可以将其替换为您自己的实现,例如:

    // using System.IO;
    static IEnumerable<string> ReadLines(string filePath)
    {
        using (var input = File.OpenText(filePath))
        {
            while (!input.EndOfStream)
            {
                string line = input.ReadLine();
                yield return line;
            }
        }
    }