0

I have the following function in my application:

// Method To Save Logs Buffer In Memory To DB
public void SaveLogsToDB()
{
    // Proceed If There Is Any Logs In Buffer
    if (LogsViewer.DBLogEntries.Count > 0)
    {
        // Init
        string massInertStr = "INSERT INTO IC_Logs ([Date], [Time], [Type], [Entry], [Synced], [CreatedOn]) VALUES ";

        // Build Mass Insert String
        List<DBLog> currentLogEntries = LogsViewer.DBLogEntries;
        foreach (DBLog myDBLog in currentLogEntries)
        {
            // Generate Insert Statement
            massInertStr += String.Format("('{0}', '{1}', '{2}', '{3}', 0, GETDATE()),",
                myDBLog.Date,
                myDBLog.Time,
                myDBLog.Type,
                myDBLog.Entry.Replace("'", "''"));
        }
        massInertStr = massInertStr.Remove(massInertStr.Length - 1);

        // Expect Errors
        try
        {
            // Execute Mass Insert
            MyDb.ExecuteNonQuery(massInertStr);

            // Clear Logs Buffer
            LogsViewer.DBLogEntries.RemoveAll(item => currentLogEntries.Contains(item));
        }
        catch { }
    }
}

When my application runs, every now and then I get the following exception:

Collection was modified; enumeration operation may not execute.

The error occurs on this line: foreach (DBLog myDBLog in currentLogEntries) { ... }

Isn't currentLogEntries a copy of the collection rather than a reference? I am not sure why this error is occurring or how to prevent it.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Latheesan
  • 23,247
  • 32
  • 107
  • 201
  • Will something like this help (before I run the foreach loop): `DBLog[] currentLogEntries = new DBLog[LogsViewer.DBLogEntries.Count]; LogsViewer.DBLogEntries.CopyTo(currentLogEntries);` ? – Latheesan Jan 05 '15 at 15:03
  • 2
    `Isn't currentLogEntries a copy of the collection rather than a reference?` No, it's a reference. – Rory McCrossan Jan 05 '15 at 15:03
  • 2
    `currentLogEntries` isn't a copy. It is the copy of the same reference. You need to take a copy of collection or use concurrent collection. Suggested duplicate should help. – Sriram Sakthivel Jan 05 '15 at 15:03
  • 1
    As an aside, look at using a `StringBuilder` when concatenating a potentially large number of strings together. – StuartLC Jan 05 '15 at 15:05
  • I am not too good at it, could someone give a lil ellaboration on why this error is occurring? I mean where is it being modified exactly (as the error says). I am sorry if the question sounds noob – Codeek Jan 05 '15 at 15:06
  • 1
    In addition to what @StuartLC said, never concatenate strings to form sql query. It is vulnerable to [SQL injection attacks](http://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/). – Sriram Sakthivel Jan 05 '15 at 15:07

1 Answers1

3

You better do this to deep clone you list:

List<DBLog> currentLogEntries = new List<DBLog>(LogsViewer.DBLogEntries);
dario
  • 5,149
  • 12
  • 28
  • 32