我正在编写一个使用文件系统的应用程序。当应用程序第一次启动时,它会运行一个快速例程,将请求的文件和文件夹加载到内存中,以便稍后进行(时间密集型)处理。(请参阅下面的代码)。在这一点上,它给出了将要处理的文件数,这对于显示进度条很重要。
一旦我有了计数和文件数据,我需要存储数据以供以后处理(例如,作为全局变量或属性或类)。问题是,由于它使用的是LINQ,所以必须将其存储为"var“。当我分解并检查变量时,它被存储为一个相当复杂的SelectQueryOperator和AnonymousType的混合。
我的第一个想法是继续循环遍历数据,并将其转换为我可以存储为List<>的简单数据(例如,存储文件名和路径),但这样做需要几分钟-最多10分钟或更长时间-处理。为了进行处理,我将不得不遍历所有这些数据,而且我的用户不可能先坐下来等待列表的建立。
我如何存储这些数据,以便我以后可以访问它,而不必首先将其转换为其他数据?
var fileNames = 
from dir in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
select dir;
var fileContents = from file in fileNames.AsParallel() 
// Use AsOrdered to preserve source ordering 
let extension = Path.GetExtension(file)
let Text = File.ReadAllText(file)
select new { Text, FileName = file }; 发布于 2012-08-18 00:28:46
让我们稍微简化一下,并在可能的情况下显式地使用var。
var fileNames = 
from dir in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
select dir;这与以下内容完全相同:
var fileNames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories);这与以下内容完全相同:
IEnumerable<string> fileNames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)现在来看一下:
var fileContents = from file in fileNames.AsParallel() 
// Use AsOrdered to preserve source ordering 
let extension = Path.GetExtension(file)
let Text = File.ReadAllText(file)
select new { Text, FileName = file }; 通常情况下,使用单行查询不会提高可读性,但为了便于讨论,它将有助于将我们的对象创建放在一个地方:
var fileContents = from file in fileNames.AsParallel() 
select new { Text = File.ReadAllText(file), FileName = Path.GetExtension(file) }; 这是匿名T的ParallelQuery<T>。为了让它成为我们可以存储的东西,我们需要停止使用匿名类:
private class NameAndContents
{
   public string Text{get;set;}
   public string FileName{get;set;}
}
ParallelQuery<NameAndContents> fileContents = from file in fileNames.AsParallel() 
select new NameAndContents{ Text = File.ReadAllText(file), FileName = Path.GetExtension(file) }; 现在没有什么可以阻止您将其存储在ParallelQuery<NameAndContents>类型的字段中。
您可能希望通过两种方式来检查这里的逻辑:
Directory.EnumerateFiles的工作原理是,它需要知道给定迭代的值才能计算下一次迭代。(它基于FindNextFile Windows API函数)。这使得它在并行化方面表现不佳。很难预测ReadAllText所涉及的固有等待会有多大程度的平衡。我不仅会在非并行版本上测试它,而且在任何更改后我都会重新测试,因为任何更改都会以一种新的方式打破这种平衡。ReadAllText。如果有可能用一种更按需使用文本的方式来取代它,那么这可能是一个巨大的胜利。https://stackoverflow.com/questions/12007640
复制相似问题