我正在使用这个代码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个驱动器~400 or需要1-1.5分钟,所以任何其他方法来加速搜索或任何调整,以获取代码。
Q3。我的程序首先列出文件,然后压缩列表中的文件。生产者-消费者的实现能提高总时间吗?
发布于 2013-06-29 13:55:20
您对returnfiles集合的访问未同步。下面的代码解决了这个问题。
公共列表execute(string filterlist,string[]驱动器){ List returnfiles =新列表();//最终列表对象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);//不应为必填项( item => returnfiles.RemoveAll == null);//删除空值返回返回文件;}
MSDN示例代码是正确的,但是您确实修改了来自多个线程的集合,这将在添加操作期间导致随机错误,因为列表集合本身不是threadsafe。您可以锁定集合,也可以使用一些线程安全的替代方法。
是的,您可以使用生产者-消费者模式来加快速度。例如,您可以使用队列而不是带有锁的列表,并在搜索文件时启动一些任务来压缩文件。这将给你的速度增加1-1.5分钟的总备份时间,这可能是值得或不值得,这取决于你做了多少备份。
另一件事是,由于您正在从5个磁盘读取,您可以为每个磁盘创建一个队列,以便您可以最大限度地使用您从中读取的磁盘的IO带宽。只有当目标备份设备能够处理增加的IO,并且您的SATA或驱动器所连接的任何总线能够处理磁盘产生的IO时,这才会有所帮助。
https://stackoverflow.com/questions/17376827
复制相似问题