There are a couple of possibilities.
First off, in most cases, Parallel.ForEach
will not spawn a new thread. It uses the .NET 4 ThreadPool (all of the TPL does), and will reuse ThreadPool threads.
That being said, Parallel.ForEach uses a partitioning strategy based on the size of the List being passed to it. My first guess is that your "outer" list has many messages, but the inner list only has one Message instance, so the ForEach partitioner is only using a single thread. With one element, Parallel
is smart enough to just use the main thread, and not spin work onto a background thread.
Normally, in situations like this, it's better to parallelize the outer loop, not the inner loop. That will usually give you better performance (since you'll have larger work items), although it's difficult to know without having a good sense of the loop sizes plus the size of the Unit of Work. You could also, potentially, parallelize both the inner and outer loops, but without profiling, it'd be difficult to tell what would be the best option.
One other possibility:
Try using [Thread.ManagedThreadId][1]
instead of Thread.CurrentThread.Name for your logging. Since Parallel
uses ThreadPool threads, the "Name" is often identical across multiple threads. You may think you're only using a single thread, when you're in fact using more than one....
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…