Jasin Ali
Jasin Ali

Reputation: 33

Argument Exception thrown by Generic.List when using AddRange with an empty Generic.List as argument

In my program I'm getting an unhandled System.ArgumentException when trying to use the AddRange function:

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

When debugging, I break on the exception on my row:

ListA.AddRange(ListB);

In the watch tool by the debugger I can see that:

ListA: Count = 2454
ListB: Count = 0

Looking at the documentation for a generic list, the ArgumentException is not listed.

Am I missing anything when trying to pin-point what exactly is going wrong?

Upvotes: -1

Views: 1070

Answers (2)

Christopher
Christopher

Reputation: 9804

Edit: Nevermind the rest of my post. It was a race condition. That happened apparently during the final AddRange part. Apparently either array was different sizes during growth step and the actuall copy. And to such a degree, the internal array had not grown enough.

A simple lock block covering all writing work on either array should fix that right up.

Original Answer - can be ignored

Your title explains it. You get a argument exception because you try to add a empty list to a existing list. This is not a valid operation according to the designers of the AddRange() Function.

ArgumentException has a very narrow purpose:

The exception that is thrown when one of the arguments provided to a method is not valid.

ArgumentException is thrown when a method is invoked and at least one of the passed arguments does not meet the parameter specification of the called method. The ParamName property identifies the invalid argument.

As it has that one purpose, it needs no special mention for every case it could happen on every single function call. Indeed you should be encounraged to throw it yourself.

To avoid this, do not feed empty lists into AddRange(). It would be trivial for checking that:

if(ListB.Lent > 0){
  ListA.AddRange(ListB);
}

As you provided 0 information on how ListB is created, we can not tell you why it sometimes is empty at this point. It just is and it is easily checked.

I use these two articles as the basis for my Exception handling:

This exception is plain and simple a case of a Boneheaded Exception. There is a remote argument for a empty list being not that Exceptional. However the designers of AddRange() felt it is exeptional enough to warant a exception. It is also trivially avoided with a basic if, so it can not really be classed as Vexing Exception. So even after all considerations, it is still just a Boneheaded exception. Please stop causing it.

Upvotes: 0

canton7
canton7

Reputation: 42225

List<T> is not thread-safe. From the docs:

Thread Safety

Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

It is safe to perform multiple read operations on a List, but issues can occur if the collection is modified while it's being read. To ensure thread safety, lock the collection during a read or write operation. To enable a collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization. For collections with built-in synchronization, see the classes in the System.Collections.Concurrent namespace. For an inherently thread-safe alternative, see the ImmutableList class.

It is not safe to write to a List<T> at the same time from multiple threads, or to write to a List<T> on one thread while reading from it on another thread. You will see random "unexplained" exceptions, like the one you're seeing.

Use a lock to properly synchronize access to your list, use a thread-safe collection, or re-architect so you don't need to do this.

Upvotes: 2

Related Questions