Why doesn't multithreading in C# reach 100% CPU? Why doesn't multithreading in C# reach 100% CPU? multithreading multithreading

Why doesn't multithreading in C# reach 100% CPU?


Do you have significant locking within your application? If the threads are waiting for each other a lot, that could easily explain it.

Other than that (and the other answers given), it's very hard to guess, really. A profiler is your friend...

EDIT: Okay, given the comments below, I think we're onto something:

The more cpu-costly part of my code is the call of a dll via COM (the same external method is called from all threads).

Is the COM method running in an STA by any chance? If so, it'll only use one thread, serializing calls. I strongly suspect that's the key to it. It's similar to having a lock around that method call (not quite the same, admittedly).


The problem is the COM object.

Most COM objects run in the context of a 'single-threaded apartment'. (You may have seen a [STAThread] annotation on the main method of a .NET application from time to time?)

Effectively this means that all dispatches to that object are handled by a single thread. Throwing more cores at the problem just gives you more resources that can sit around and wait or do other things in .NET.

You might want to take a look at this article from Joe Duffy (the head parallel .NET guy at Microsoft) on the topic.

http://www.bluebytesoftware.com/blog/PermaLink,guid,8c2fed10-75b2-416b-aabc-c18ce8fe2ed4.aspx

In practice if you have to do a bunch of things against a single COM object like this you are hosed, because .NET will just serialize access patterns internally behind your back. If you can create multiple COM objects and use them then you can resolve the issue because each can be created and accessed from a distinct STA thread. This will work until you hit about 100 STA threads, then things will go wonky. For details, see the article.


It is probably no longer the processor that is the bottleneck for completing your process. The bottleneck has likely moved to disk access, network access or memory access. You could also have a situation where your threads are competing for locks.

Only you know exactly what your threads are doing, so you need to look at them with the above in mind.