TraverseTreeParallelForEach MSDN示例异常
本文关键字:异常 MSDN TraverseTreeParallelForEach | 更新日期: 2023-09-27 18:20:17
我使用的是TraverseTreeParallelForEach 代码
有时我会神秘地得到聚合异常。Add(T)处的数组索引越界异常。我正在将其用于我的备份程序。
public List<string> execute(string filterlist, string[] drives)
{
List<string> returnfiles = new List<string>(); // final list
foreach (string drive in drives)
{
foreach (string filter in filterlist.Split(','))
{
TraverseTreeParallelForEach(drive, filter, (f) =>
{
returnfiles.Add(f);
});
}
}
Console.WriteLine("Returnfiles count " + returnfiles.Count);
returnfiles.RemoveAll(item => item == null); //remove nulls
return returnfiles;
}
Q2.目前搜索5个驱动器~400GB需要1-1.5分钟,所以任何其他方法都可以加速搜索或对代码进行任何调整。
Q3.我的节目首先列出了&然后压缩列表中的文件。生产者-消费者的实施能否提高总时间?
您对returnfiles集合的访问不同步。下面的代码确实解决了这个问题。
public List execute(string filterlist,string[]个驱动器){List returnfiles=new List();//最终清单object lockObj=新对象();
foreach (string drive in drives)
{
foreach (string filter in filterlist.Split(','))
{
TraverseTreeParallelForEach(drive, filter, (f) =>
{
lock(lockObj)
{
returnfiles.Add(f);
}
});
}
}
Console.WriteLine("Returnfiles count " + returnfiles.Count);
//不应该是必要的返回文件。RemoveAll(item=>item==null)//删除null返回返回文件;}
MSDN示例代码是正确的,但您确实修改了来自多个线程的集合,这将在添加操作期间导致随机错误,因为List集合本身并不线程安全。您可以锁定集合,也可以使用一些线程安全的替代方法。
是的,你可以使用生产者-消费者模式来加快速度。例如,您可以使用"队列"而不是带锁的列表,并在搜索文件时启动一些任务来压缩文件。这将使您的总备份时间最多增加1-1.5分钟,这可能是值得的,也可能是不值得的,这取决于您做了多少备份。
另一件事是,由于您从5张光盘中读取,您可以为每张光盘创建一个队列,这样您就可以最大限度地提高从中读取的光盘的IO带宽。只有当目标备份设备能够处理增加的IO,并且您的SATA或驱动器连接的任何总线能够处理磁盘产生的IO时,这才有帮助。