When you start your tasks, you loop is starting remainingTasks
tasks. By the time you near 10000, however, some of the tasks have completed and decremented this number to less than 10000, so you do not start the proper number of tasks. If I modify your loop to save how many tasks should be started, the code runs successfully. (Note that you should also be checking the return value of QueueUserWorkItem
.)
int toStart = remainingTasks;
for (int i = 0; i < toStart; i++)
{
if (!ThreadPool.QueueUserWorkItem(delegate { TestInterlockedDecrement(); }))
Console.WriteLine("Queue failed");
}