简体   繁体   中英

Exception while removing items from a collection inside a delegate

I have List<ActiveDeviceProcess> which keeps the windows forms. When I call the activeDeviceProcessFormClosed(deviceNumber) from another form via FormClosing listener. I got an error. But I don't know why. Everything look like fine. Here is my method:

public void activeDeviceProcessFormClosed(int deviceNumber)
{
     this.Invoke((MethodInvoker)delegate
     {
         foreach (ActiveDeviceProcess i in activeDeviceProcessForms)
         {
             if (i.device.deviceNumber == deviceNumber)
             {
                 activeDeviceProcessForms.Remove(i);
             }
         }
     });
}

Here is the error:

An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code

Thanks for your help!

You can't remove items from a collection while iterating it. Use List<T>.RemoveAll instead:

public void activeDeviceProcessFormClosed(int deviceNumber)
{
     this.Invoke((MethodInvoker)delegate
     {
        activeDeviceProcessForms.RemoveAll(i => i.Device.DeviceNumber == deviceNumber);
     });
}

Edit:

If you only have multiple items with the same device id want to remove the first element that has that DeviceNumber , you can use Enumerable.FirstOrDefault and List<T>.Remove :

public void activeDeviceProcessFormClosed(int deviceNumber)
{
     this.Invoke((MethodInvoker)delegate
     {
        var device = activeDeviceProcessForms.FirstOrDefault(
                        i => i.Device.DeviceNumber == deviceNumber);

        if (device != null)
            activeDeviceProcessForms.Remove(device);
     });
}

Since, it is iterating, when I remove an element inside the list I should add "break" command.

public void activeDeviceProcessFormClosed(int deviceNumber)
{
     this.Invoke((MethodInvoker)delegate
     {
         foreach (ActiveDeviceProcess i in activeDeviceProcessForms)
         {
             if (i.device.deviceNumber == deviceNumber)
             {
                 activeDeviceProcessForms.Remove(i);
                 break;//----> this was added.
             }
         }
     });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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