如何处理Enumerator文件或Enumerator文件夹上PLINQ查询中的c#异常
我遇到了一些不错的帖子,使用下面的代码获得了文件和/或文件夹的总数:如何处理Enumerator文件或Enumerator文件夹上PLINQ查询中的c#异常,c#,linq,exception-handling,C#,Linq,Exception Handling,我遇到了一些不错的帖子,使用下面的代码获得了文件和/或文件夹的总数: DirectoryInfo dirInfo = new DirectoryInfo(myBaseDirectory + @"\"); var count = await Task.FromResult(dirInfo.EnumerateDirectories() .AsParallel() .SelectMany(di =>
DirectoryInfo dirInfo = new DirectoryInfo(myBaseDirectory + @"\");
var count = await Task.FromResult(dirInfo.EnumerateDirectories()
.AsParallel()
.SelectMany(di => di.EnumerateFiles("*.*", SearchOption.AllDirectories))
.Count() + dirInfo.EnumerateFiles("*.*", SearchOption.TopDirectoryOnly).Count());
这很有效。直到我尝试访问NTFS格式的驱动器。然后在EnumerateFiles函数上引发异常。这是卷信息文件夹上的UnauthorizedAccessException
现在我的问题是,我如何重写这段代码,当抛出异常时,代码保持“循环”。换句话说,它只是跳过引发异常的文件或文件夹
我试着理解整个代码不起作用。就我现在所知,我应该在selectMany部分尝试一下。比如:
.SelectMany(di => { try { di.EnumerateFiles("*.*", SearchOption.AllDirectories); } catch{ }})
但是代码没有编译。有什么建议吗?当存在try..catch inside()之类的块语句时,不能使用短lambda语法(这意味着将其唯一语句的表达式值作为返回值)。在您的情况下,需要使用
return
语句来指示哪个表达式是lambda函数的结果:
SelectMany(di => {
try
{
return di.EnumerateFiles("*.*", SearchOption.AllDirectories);
}
catch
{
/* just skip */
return new FileInfo[] { };
}
})
什么是编译器错误?除了速度非常慢之外,它还应该起作用。没有规则可以阻止lambda函数体中的try…catch。try…catch构造不返回任何内容,因此对于SelectMany无效。尝试将
return
放在di.EnumerateFiles
之前,并在catch中返回一个空枚举(您也可能会显式捕获UnauthorizedAccessException
,但仍会引发其他意外错误)。您确定并行实际上会提高性能吗?我猜,这会增加磁盘抖动,实际上会降低性能。您可以同时发出许多IO请求,但您仍然只有一个硬盘驱动器的运行速度比单个同步线程慢得多。@dlatikay如果速度慢得多,您有什么建议?@Me.Name我会尝试一下。是谁干的。非常感谢。这是与Me.name相同的解决方案。到目前为止没有性能问题