首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使"var“成为全局的或持久的?

如何使"var“成为全局的或持久的?
EN

Stack Overflow用户
提问于 2012-08-17 22:23:32
回答 5查看 221关注 0票数 0

我正在编写一个使用文件系统的应用程序。当应用程序第一次启动时,它会运行一个快速例程,将请求的文件和文件夹加载到内存中,以便稍后进行(时间密集型)处理。(请参阅下面的代码)。在这一点上,它给出了将要处理的文件数,这对于显示进度条很重要。

一旦我有了计数和文件数据,我需要存储数据以供以后处理(例如,作为全局变量或属性或类)。问题是,由于它使用的是LINQ,所以必须将其存储为"var“。当我分解并检查变量时,它被存储为一个相当复杂的SelectQueryOperator和AnonymousType的混合。

我的第一个想法是继续循环遍历数据,并将其转换为我可以存储为List<>的简单数据(例如,存储文件名和路径),但这样做需要几分钟-最多10分钟或更长时间-处理。为了进行处理,我将不得不遍历所有这些数据,而且我的用户不可能先坐下来等待列表的建立。

我如何存储这些数据,以便我以后可以访问它,而不必首先将其转换为其他数据?

代码语言:javascript
运行
复制
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 }; 
EN

Stack Overflow用户

回答已采纳

发布于 2012-08-18 00:28:46

让我们稍微简化一下,并在可能的情况下显式地使用var

代码语言:javascript
运行
复制
var fileNames = 
from dir in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
select dir;

这与以下内容完全相同:

代码语言:javascript
运行
复制
var fileNames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories);

这与以下内容完全相同:

代码语言:javascript
运行
复制
IEnumerable<string> fileNames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)

现在来看一下:

代码语言:javascript
运行
复制
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 }; 

通常情况下,使用单行查询不会提高可读性,但为了便于讨论,它将有助于将我们的对象创建放在一个地方:

代码语言:javascript
运行
复制
var fileContents = from file in fileNames.AsParallel() 
select new { Text = File.ReadAllText(file), FileName = Path.GetExtension(file) }; 

这是匿名TParallelQuery<T>。为了让它成为我们可以存储的东西,我们需要停止使用匿名类:

代码语言:javascript
运行
复制
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>类型的字段中。

您可能希望通过两种方式来检查这里的逻辑:

  1. Directory.EnumerateFiles的工作原理是,它需要知道给定迭代的值才能计算下一次迭代。(它基于FindNextFile Windows API函数)。这使得它在并行化方面表现不佳。很难预测ReadAllText所涉及的固有等待会有多大程度的平衡。我不仅会在非并行版本上测试它,而且在任何更改后我都会重新测试,因为任何更改都会以一种新的方式打破这种平衡。
  2. 这里最大的冲击是ReadAllText。如果有可能用一种更按需使用文本的方式来取代它,那么这可能是一个巨大的胜利。
票数 1
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12007640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档