【问题标题】:C# Using ArrayList.IndexOf with multiple identical itemsC# 使用具有多个相同项目的 ArrayList.IndexOf
【发布时间】:2016-11-08 02:30:20
【问题描述】:

我有一种情况,我使用 ArrayList 来存储文件名列表(完整文件路径)。当我将同一文件的多个项目添加到数组中,然后使用 ArrayList.IndexOf 查找索引(我正在向 BackgroundWorker 报告进度)时,它始终返回第一项的索引,因为它是按文件名搜索的。这会导致进度条出现问题,即我正在处理 3 个文件,完成后,进度条只有 1/3。

这是一些示例代码(我只是在这里添加项目,但在实际代码中它们是从 ListBox 添加的):

ArrayList list = new ArrayList();

list.Add("C:\Test\TestFile1.txt");
list.Add("C:\Test\TestFile1.txt");
list.Add("C:\Test\TestFile1.txt");

var files = list;
foreach (string file in files)
    backgroundWorker1.ReportProgress(files.IndexOf(file) + 1);

运行时,仅报告 1“百分比”的进度,因为 IndexOf 每次都在查找相同的文件。有没有办法解决?或者是否有人对获取索引(或每个项目的任何唯一标识符)的另一种方式提出建议?

【问题讨论】:

  • 顺便说一句,您使用ArrayList 而不是List<string> 有什么原因吗?通常应避免使用非泛型集合。它们在那里是为了向后兼容,但过去 10 年编写的代码最好不要使用它们。
  • 为什么你的文件在同一个列表中多次出现?是否需要多次或单次处理?
  • 您可以使用for 循环并使用递增变量而不是IndexOf

标签: c# arraylist


【解决方案1】:

最简单的方法就是使用索引来迭代:

for (int i = 0; i < list.Count; i++)
{
    backgroundWorks.ReportProgress(i + 1);
    // Do stuff with list[i]
}

【讨论】:

  • 谢谢,我不知道为什么我没想到。我想我最初使用的是 ArrayList,因为我使用的是一个需要它的旧库(可能是旧版本的 .NET)。我将我的代码转换为使用 List ,就像一个魅力。
【解决方案2】:

为了实现你想要的,我建议使用for 列表。您无需搜索任何索引,并且可以轻松地将进度报告给backgroundWorker1

for (int counter = 0; counter < files.Count; counter++)
{
    backgroundWorker1.ReportProgress(counter + 1);
}

通过这样做,您不会遇到文件名相同的问题。

这相当于foreach:

int counter = 1;
foreach (string file in files)
{
    backgroundWorker1.ReportProgress(counter);
    counter++;
}

但我认为在这种情况下最好使用for

【讨论】:

    【解决方案3】:

    您可以复制您的列表,然后在处理过程中从中删除每个项目。然后,您可以将完成百分比作为临时列表计数除以原始列表计数的函数返回。

    您也可以在后台工作人员每次处理文件时添加一个 int 并使用该 int 来跟踪进度(完成百分比应该是 int 除以文件数)。

    当然,无论使用哪种方法,您都需要确保以线程安全的方式修改相关变量。

    【讨论】:

      【解决方案4】:

      试试这个,在读取包含这么多数据行的文件时,它对我来说效果很好。

        int percentage = (int)((count / (double)lineCount) * 100.0);
        backgroundWorker5.ReportProgress(percentage);
      

      这里的 count 是总计数,而 linecount 是当前的运行计数。通过使用这两个,计算百分比。将此代码保留在您的 for 循环或 while 循环中。

      【讨论】:

        【解决方案5】:

        假设进度条最大值为 100,并且处理了三个文件中的一个文件,它应该显示 33(%) 进度,您可以计算每个已处理文件的进度并重新计算整体进度:

        // list contains x file paths
        var files = list;  
        
        double progressStep = 1 / files.Count;
        
        for(int i = 0; i < files.Count; i++)
        {
            backgroundWorker1.ReportProgress((i + 1) * progressStep);
            ...
        }
        

        剩下的就是将后台工作人员中的进度值分配给进度条。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-04
          • 2014-09-07
          • 1970-01-01
          • 2012-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多