What is the scope of the lock?

I've seen this piece of code from one of the jetbrain's team :

Looking at this code :

object myLock = new object()

public IEnumerable<int> Values()
{
 lock (myLock)
 {
   for (var i=0;i<10;i++)
     yield return i;
 }
}



public void Test()
{
 foreach (var value  in Values())
  {
    DoHugeJob(value);   
  }
}


void Main()
{
    Test();
}

Question:

What is the scope of the lock?

Jon Skeet
people
quotationmark

If you mean in terms of time - the lock will be aquired when MoveNext() is first called, and will be released either when MoveNext() has been called for the 11th time (i.e. when the loop completes) or when the iterator is disposed.

For example:

var iterable = Values();
// Lock is *not* acquired yet...

foreach (var item in iterable.Take(5)) {
    // Lock has been acquired
}
// Lock has been released even though we didn't get to the
// end of the loop, because foreach calls Dispose

In general it's a bad idea to lock in iterator blocks precisely because of this - you really want to lock for a short, easily-understood period of your program.

people

See more on this question at Stackoverflow