C# preventing Collection Was Modified exception

前端 未结 10 1753
梦毁少年i
梦毁少年i 2021-01-17 17:16

Does

 foreach(T value in new List(oldList) )

is dangerous (costly) when oldList contains 1 millions of object T ?

More g

相关标签:
10条回答
  • 2021-01-17 18:06

    you can use a flag to switch the modification to a temporary list while the original is being enumerated.

    /// where you are enumerating

    isBeingEnumerated = true
    foreach(T value in new List<T>(oldList) )
    isBeingEnumerated = false
    SyncList(oldList with temporaryList)
    

    /// where you are modifying while enumerating

    if isBeingEnumerated then
    use a temporaryList to make the changes.
    
    0 讨论(0)
  • 2021-01-17 18:15

    It will be 'slow' but there is not much more you can do about it, except running it on a background thread. E.g. using a BackgroundWorker.

    If your operations on the list only occur on one thread, the correct approach is to add the items to add/remove to seperate lists, and perform those operations after your iterations has finished.

    If you use multiple threads you will have to look into multithreaded programming, and e.g. use locks or probably better a ReaderWriterLock.

    UPDATE: As mentioned in another Stack Overflow question, this is now possible without any effort in .NET 4.0 when using concurrent collections.

    0 讨论(0)
  • 2021-01-17 18:16

    If you mean you can add/remove objects from another thread, I would: 1-synchronize the threads 2- in the add/remove threads, create a list of items to be added or deleted 3- and then delete these items in a critical section (so it is small - you don't have to synch while adding the items to the delete list)

    If you dont want to do that, you can use for instead of foreach, that would avoid the exception, but you would have to take extra care so you do not get other kinds of exceptions

    0 讨论(0)
  • 2021-01-17 18:17

    If you are using Foreach loop for modifying collection then you will get this error as below.

    List<string> li = new List<string>();
        li.Add("bhanu");
        li.Add("test");
    
        foreach (string s in li)
        {
            li.Remove(s);
        }
    

    Solution - use For Loop as below.

    for (int i = 0; i < li.Count; i++)
        {
            li.RemoveAt(i);
            i--;
        }
    
    0 讨论(0)
提交回复
热议问题