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.我的节目首先列出了&然后压缩列表中的文件。生产者-消费者的实施能否提高总时间?

TraverseTreeParallelForEach MSDN示例异常

您对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时,这才有帮助。