Weird lock () behavior with foreach

So this is not my code and has been shortened to show behavior, but it gives very unexpected results.

I have two functions in the class and lock

object mylock = new object(); List<string> temp = new List<string>(); Func1(string) { lock(mylock) { temp.Add(string); } } Func2() { lock(mylock) { temp.ForEach(p => Func1(p)); } } 

Now I know that this makes no sense, but when Func2 is called, should Func1 not hang? In our case, it is executed. Thanks.

+4
source share
3 answers

No, he should not come to a standstill.

Func1 can get a lock if it is called by someone who already has a lock (e.g. Func2 )

The MSDN doc for locking explains:

"While the mutual exclusion lock is retained, code executing in the same execution thread can also receive and release the lock. However, code execution in other threads is blocked from receiving the lock until the lock is released."

The purpose of blocking is to prevent different threads from accessing the same resource. Func1 and Func2 are in the same thread .

+13
source

The lock statement ( Monitor encapsulating class) supports re-entry (recursion) in the stream, i.e. You can nest calls that use the same monitor.

Other locking methods:

  • Monitor - recursion supported
  • ReaderWriterLock - recursion supported but slow
  • ReaderWriterLockSlim - recursion supported but not recommended
  • EventHandle ( ManualResetEvent , AutoResetEvent , Mutex , Semaphore ) - recursion is not supported
+3
source

.NET Monitor objects (the use of which is used) are recursive, so the thread holding the lock can re-enter this lock.

(Not all blocking constructs are recursive, and arguments can be made against recursive support.)

+1
source

All Articles