【发布时间】:2013-02-18 15:29:34
【问题描述】:
我有以下方法返回目录中的文件列表:
public IEnumerable<FileInfo> GetFilesRecursiveEnumerable(DirectoryInfo dir)
{
if (dir == null) throw new ArgumentNullException();
IList<FileSystemInfo> files = new List<FileSystemInfo>();
try
{
files = dir.GetFileSystemInfos();
}
catch (UnauthorizedAccessException) { } //ignore
catch (PathTooLongException)
{
MessageBox.Show("Path too long in directory: " + dir.FullName);
}
foreach (FileSystemInfo x in files)
{
DirectoryInfo dirInfo = x as DirectoryInfo;
if (dirInfo != null)
{
foreach (FileInfo f in GetFilesRecursiveEnumerable(dirInfo))
{
yield return f;
}
}
else
{
FileInfo fInfo = x as FileInfo;
if (fInfo != null) yield return fInfo;
}
}
}
此方法会阻止 GUI。我想在后台线程中运行它(仅限单个),以便当FileSystemInfo 对象可用时,它会提供给调用者。
我已经能够让这个方法在后台工作程序中运行并返回FileSystemInfos 中的ICollection - 但这会返回整个列表,而我想在找到项目时生成它们。
编辑
似乎我可能需要重新评估我想要实现的目标(也许这需要回调而不是 IEnumerable)
基本上,我希望索引一个驱动器价值的文件,但我想在后台线程中运行它。这样,我可以逐个文件处理(可能是 Dir by Dir),如果需要,我可以在稍后阶段恢复该过程。如此有效,我希望调用者(GUI 线程)运行此方法,但在目录扫描期间收到通知,而不是在扫描完成时收到通知。比如,
//My original thoughts, but maybe need to tackle this a different way
public void ScanDrive()
{
foreach(FileInfo f in GetFilesRecursiveEnumerable())
{
//index file
//record the directory I am up to so I can resume later
/Keeping my application responsive to perform other tasks
}
}
【问题讨论】:
-
事实上,这将运行得如此之快,以至于您必须放慢整个过程才能让用户看到更新。这是毫无意义。而且该模式与您的要求不匹配——您需要某种回调而不是收益。并且考虑到您必须将对回调的每个调用编组到 UI 线程上,您最终会在 UI 线程上运行此方法。免得惹恼自己。
-
用户不会看到更新,而是我要索引文件。我不想将整个 Drive 的文件传递给调用者,而是希望以增量方式执行它们,这样我就有可能恢复驱动器的索引。
-
您似乎遇到了不同的问题。不确定索引是什么意思,但您可能想要edit 并添加对您实际尝试完成的内容的描述。可能会得到一些更好的答案。
-
This blog post 有很多关于这个特定主题的信息,也许您可以根据自己的需要使用其中的一些信息。
-
您需要在后台线程中运行调用它的代码,而不是单独运行此代码。
标签: c# backgroundworker yield