繁体   English   中英

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

[英]Collection was modified in foreach loop C#

我知道有很多类似的问题,但我似乎无法深入探讨这个问题。

在我的程序中,我执行了一种验证方法,该方法应相互比较两个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()添加到foreach externalProgram中,但这没有任何区别。 在执行期间如何修改我的externalProgram

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

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

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

此示例: 在多线程方案中正确锁定List <T>? 更好地描述了我的意思。

这行可能是个问题:

externalProgram.RemoveAt(externalProgram.Count - 1);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM