Usually, something like this is done using worker threads. You create a list of work items (= your listbox entries):
List<WorkItem> myWorkItems = ...; // contains 10 items
And you create your threads. You do not, however, assign a work item to the thread yet (as you do in your example):
for (int i = 0; i < numberOfThreads; i++) { // creates 5 threads
var t = new Thread(doWork);
t.IsBackground = true;
t.Start();
}
Each thread runs a loop, checking for new work items (thread-safe!) and doing work, until no more work is to be done:
void doWork() {
while (true) {
WorkItem item;
lock(someSharedLockObject) {
if (myWorkItems.Count == 0)
break; // no more work to be done
item = myWorkItems[0];
myWorkItems.Remove(item);
}
doTask(item);
}
}
This is similar to what the ThreadPool of the .net Framework does. The ThreadPool, however, is designed to work best when the number of threads can be chosen be the Framework. The example above gives you full control over the number of threads (which seems to be what you want).