0

I've read this patterns but found it not to work. I get a rare exception that an item in foreach was changed.

lock (mylist) { foreach(var a in myList) {}

myList = new List<>() (or myList.Clear() ) }

I also tried this

foreach(var a in myList.ToList() ) { }

And that also generated exceptions. There are some other patterns described in this thread but I want to confirm/understand why above patterns didnt work I've read a bit about how to properly lock a list. The exception doesn't occur often-- just very rarely and there was also a memory leak at the time.

1. Do I need to use the lock everywhere I modify myList or does the lock prevent anyone from editing mylist? This may be the source of confusion.

2.

Is there a difference in lock mylist and casting and using syncroot?

See here

Properly locking a List<T> in MultiThreaded Scenarios?

Community
  • 1
  • 1
Curtis White
  • 6,213
  • 12
  • 59
  • 83
  • Concerning 1: Yes, you need to lock everywhere you modify the list or even read from it. That's how locks are supposed to be used. – ilmiacs Jan 15 '13 at 17:02
  • There's a great ( and free ) ebook here: [`Albahari`](http://www.albahari.com/threading/) – Nick Butler Jan 15 '13 at 17:10

1 Answers1

1

Generally, if you have a shared resource then you need to lock a mutex that protects the resource whenever you use this resource. Does not matter if it's just reading or writing. If mutex is not locked in at least one of the places that you use the shared resource, you have a problem. For example, if you only lock a shared resource while modifying it, then it is possible that some thread is reading it while another is modifying it - a situation known as race condition occurs.

In your particular case, yes, you need to lock mylist everywhere you modify it. And not only where you modify it, but also everywhere you read it.

sdkljhdf hda
  • 1,387
  • 9
  • 17