每个都有一个动态列表

本文关键字:动态 列表 有一个 | 更新日期: 2023-09-27 17:57:51

我有一个for each循环,它在数据库中运行,以检查已标记为要转换的文件。目前我有以下代码:

            /* All files flagged for invidual conversion will be stored in here. */
            ArrayList files = vc.getFilesForInvidualConversion();
            foreach (FileInfoExtended file in files)
            {
                // As long as the status flag hasn't been changed it can continue.
                if (abort == false)
                {
                    if (vc.isFileInUse(file) == false)
                    {
                            // Converting the video file.
                            vc.convertVideoToFLV(file);
                    }
                }
                vc.getFilesForInvidualConversion();
            }

在第一行中,你可以看到我用对象填充了一个ArrayList,它将用for each来遍历这些对象。但是,在列表中的每个文件之后,我都想检查是否有可能需要转换的新文件。当我再次填充ArrayList时,for each似乎没有注意到,它会继续使用从第一行代码中收到的原始文件。我宁愿它更新"文件"-ArrayList,这样它也可以转换新文件。

这可能吗?

编辑:您给出的答案都适用于此场景,但我想添加一些内容。循环过程中是否可以从列表中删除文件?为了让它不会改变这一点?

第2版:这就是我现在拥有的:

            List<FileInfoExtended> files = vc.getFilesForInvidualConversion();
            while (files.Count > 0)
            {
                if (abort == false)
                {
                    if (vc.isFileInUse(files[0]))
                    {
                        vc.convertVideoToFLV(files[0]);
                    }
                }
                files = vc.getFilesForInvidualConversion();
            }

它在这两种情况下都有效(当文件被添加到列表中时和当文件被从列表中删除时)。我不知道这是否是一个性能方面的好解决方案,但现在它适合我的需求。除非我忽略了一些问题?

任何评论都将不胜感激!谨致问候,Floris

每个都有一个动态列表

我建议使用其他集合,而不是ArrayList。例如CCD_ 2。然后这样写smth:

while (stack.Any())
{
    var item = stack.Pop();
    // convert item
}
// All items were converted

在任何时候,您都可以stack.Push()新项目。

第页。S.:使用非通用ArrayList有什么意义吗?

您可以使用标准的"for"循环。foreach循环要求集合在遍历过程中是不可变的。"for"循环没有此约束。但是,在这种情况下,获取"for"循环的结束条件约束可能很困难。

我会考虑保留一个已经处理的文件列表,这样当您第二次通过时,您就可以检查是否已经处理了特定的文件。

实现这一点的明智方法是处理批次:当每个批次完成时,获得另一个批次,直到达到空批次(这与@j0rd4n建议的方法相同)。以下是如何将这个逻辑封装在一个漂亮的foreach循环中:首先,创建一个类来管理迭代:

namespace StackOverflow6128549
{
    class FileInfoExtended
    {
        public int PropertyX { get; set; }
    }
    class IncrediblySmartIteration : IEnumerable<FileInfoExtended>
    {
        private List<FileInfoExtended> GetFilesToProcess()
        {
            throw new NotImplementedException();
        }
        #region IEnumerable<FileInfoExtended> Members
        private IEnumerator<FileInfoExtended> InternalGetEnumerator()
        {
            List<FileInfoExtended> filesToProcess = null;
            do
            {
                filesToProcess = GetFilesToProcess();
                foreach (var fi in filesToProcess)
                {
                    yield return fi;
                }
            }
            while (filesToProcess.Count > 0);
        }
        public IEnumerator<FileInfoExtended> GetEnumerator()
        {
            return InternalGetEnumerator();
        }
        #endregion
        #region IEnumerable Members
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return InternalGetEnumerator();
        }
        #endregion
    }
}

然后,您将能够使用简单的foreach:运行这种类型的对象

        var container = new IncrediblySmartIteration();
        foreach (var fi in container)
        {
            Console.WriteLine(fi.PropertyX);
        }

请注意,在设计GetFilesToProcess()方法时,应该注意保证终止。请务必考虑在查找新文件时出现错误时会发生什么。

您可以使用递归将索引传递给递归函数,以便评估您在数组中的位置。

void ConvertRecursively(int index, typeForVC vc)
{
   if(abort)
      return;
   ArrayList files = vc.getFilesForInvidualConversion();
   if(index !< files.Count)
       return;
   else 
   {
      if (vc.isFileInUse(files[index]) == false)
       {
           // Converting the video file.
           vc.convertVideoToFLV(files[index]);
       }
       return ConvertRecursive(++index, vc);
   }
}

打电话只需做:

ConvertRecursively(0, typeForVC vc);

更新:如果您需要处理数组大小也减小的情况,同样,最后一条流控制语句是不必要的,所以我去掉了它:

void ConvertRecursively(int index, int prevSize, typeForVC vc)
{
   if(abort)
      return;
   ArrayList files = vc.getFilesForInvidualConversion();
   int sizeDifferential = files.Count <= prevSize ? prevSize - files.Count : 0;
   int adjustedIndex = index - sizeDifferential;
   if(adjustedIndex !< files.Count)
       return;
      if (vc.isFileInUse(files[adjustedIndex]) == false)
       {
           // Converting the video file.
           vc.convertVideoToFLV(files[adjustedIndex]);
       }
       return ConvertRecursive(++adjustedIndex, files.Count, vc);     
}

打电话只需做:

ConvertRecursively(0, 0, typeForVC vc);

好的,现在我只是玩得很开心。希望它对你有用。我还没有测试过这个b.t.w.