My comments got quite long, so I decided to make this a separate post.
First, +1 for Fredrik Mörk, using VirtualMode
is the way to go. However, you do lose some functionality, e.g. column autosize, and sorting is easier handled on your own.
If that is a problem, populating from a worker thread may sound sounds tempting. However, the population will still take place in the thread that owns the list control (i.e. virtually always the main thread) - .NET makes that visible by enforcing you to use (Begin)Invoke
. Additionally, the context switches will notably increase the total time you need to fill all items if you fill one by one, so you want to fill in chunks (say 50 items at a time, or even better fill as many as you can in 20 milliseconds). Add to that the additional synchronization required when contents changes, you have a quite complex solution for a not-so-stellar result.