在foreach循环C#中修改了集合

时间:2013-11-26 11:39:16

标签: c# exception foreach

我知道有很多类似的问题,但我似乎无法深究这一点。

在我的程序中,我执行一个验证方法,该方法应该将两个ascii HEX文件相互比较(一个是本地的,另一个是从USB设备读取的)。一些代码:

private void buttonVerify_Click(object sender, EventArgs e)
{
    onlyVerifying = true;

    Thread t = new Thread(verifyProgram);
}
private void verifyProgram()
{
    verifying = true;
    externalFlashFile.Clear();

    // After this method is finished, the returned data will end up in 
    // this.externalFlashFile since this listen to the usb's returned data
    hexFile.readExternalFlashForVerify(usbDongle, autoEvent);

    externalFlashFile.RemoveAt(0);
    //externalFlashFile.RemoveAt(externalFlashFile.Count - 1);
    hexFile.verifyProgram(externalFlashFile);
}

public void verifyProgram(List<string> externalProgram)
{
    byte[] originalFile = null; // Will be modified later with given size
    byte[] externalFile = new byte[4096];
    int k = 0, errors = 0;

    // Remove last line which contains USB command data
    externalProgram.RemoveAt(externalProgram.Count - 1);

    foreach (String currentLine in externalProgram)
    {
        for (int i = 0; i < 64; i += 2)
        {
            string currentDataByte = currentLine.Substring(i, 2); 
            externalFile[k] = Convert.ToByte(currentDataByte, 16);
            k++;
        }
        progress += steps;
    }
//... compare externalFile and originalFile

执行readExternalFlashForVerify时,USB正在响应请求的数据。解析此数据并调用事件处理程序:

public void usbDongle_OnDataParsed(object sender, EventArgs e)
{
  if (verifying)
  {
      usbDongle.receivedBytesString.Trim();
      externalFlashFile.Add(usbDongle.receivedBytesString.Substring(2, 32 * 2));
      // Allow hexFile continue its thread processing
      autoEvent.Set();
  }
}

第一次运行始终正确完成。以下执行,在foreach的第三次或第四次迭代中,我在externalProgram中得到了一个额外的元素。这不是一个全局变量(函数调用中的参数),并且该函数不会在其他任何地方调用。这个例子引发了一个例外。

我尝试在.ToList()中将externalProgram添加到foreach,但这没有任何区别。如何在执行期间修改externalProgram

编辑:我从来没有找到原因,但用硬编码foreach替换for-loop解决了手头的问题。不是最佳解决方案,但没有太多时间。

// The list should never be larger than 128 items
for (int j = 0; j < 0x7f ; j++)
{
     string currentLine = externalProgram[j];
     // ...

2 个答案:

答案 0 :(得分:0)

通常当您收到带有类似消息的异常时,它是由从不同线程到列表的多次访问引起的。 我建议你在添加和删除该列表中的项目时使用锁定,这样你就可以确定该集合的索引没有改变。您必须考虑如果您尝试在其他人删除前一个项目时将某个集合的最后一个元素(例如索引3)删除(将集合的长度更改为3 ...),将会发生什么。

这个例子:Properly locking a List<T> in MultiThreaded Scenarios?更好地描述了我的意思。

答案 1 :(得分:0)

这条线可能是个问题:

externalProgram.RemoveAt(externalProgram.Count - 1);

如果多次调用verifyProgram,它将从引用传递的externalProgram列表中删除越来越多的行