4

why this lock test doesn't work ? it's throwing an exception bellow Console.Write that collection was modified....

    static List<string> staticVar = new List<string>();

    static void Main(string[] args)
    {
        Action<IEnumerable<int>> assyncMethod = enumerator =>
                {
                    lock (staticVar)
                        foreach (int item in enumerator)
                            staticVar.Add(item.ToString());


                };

        assyncMethod.BeginInvoke(Enumerable.Range(0, 500000), null, null);
        Thread.Sleep(100);

        Console.Write(staticVar.Count());
        foreach (string item in staticVar)
        {

        }
    }
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
Alexandre
  • 7,004
  • 5
  • 54
  • 72

1 Answers1

5

In order for a lock to be effective it must be used in all cases that a collection is accessed. Be it reading or writing. So you must add a lock before enumerating the collection

For example

lock (staticVar) {
    Console.Write(staticVar.Count());
    foreach (string item in staticVar) {

    }
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • only to collection or all types ? – Alexandre May 20 '10 at 17:27
  • 2
    The point of a lock is that nothing can enter the lock if it is held elsewhere. The lock can have no effect on a chunk of code if it is not around it. A lock must wrap every section of code which uses a synchronised variable. – Martin May 20 '10 at 17:31