SyncLock on List in Multithread still throws ArgumentException

423 views Asked by At

I need to read from a list on a (background) thread while it may be updated from another (main thread). So I try to just make a temporary list not to access the original object. As updates may occur on multiple places, it would be convenient to place SyncLock on the read logic. Is that inherently wrong? What are my options for locking this correctly, or other ways to acquire an accessible copy of the list in a multithread condition?

 ' In Main thread: 
 Public SomeList = New List(Of SomeClass) 
 ' ..edit list


 ' In other thread: 
  Dim tempList As List(Of SomeClass)
  SyncLock SomeList
      tempList = SomeList.ToList
  End SyncLock

SomeList.ToList throws:

ArgumentException, Destination array was not long enough. Check destIndex and length, and the array's lower bounds.

2

There are 2 answers

1
Mark Hurd On BEST ANSWER

After reviewing .ToList and thus New List(Of SomeClass)(.), in Reflector, the exception must be coming from is2.CopyTo(Me._items, 0) where Me._items has just been set to New T(count - 1) {}.

This means the number of items in the input collection (cast to ICollection(Of T) in is2) must have increased after is2.Count was retrieved.

As such, I re-ask the assumption in my now deleted answer: Do all places in the Main thread, in ' ..edit list, also use SyncLock SomeList when modifying the list?

2
M Afifi On

Not sure what the equivalent is in VB, but can't you do something like this?

IList<string> roDinosaurs = dinosaurs.AsReadOnly();

Or

tempList.AddRange(SomeList);