Creating Threads on Gallery Server -- Performance Issue?

Jan 9, 2011 at 12:48 PM

When a package download or rating occurs, we do the download incrementing / rating on a new thread so that the user can immediately receive the package download / rating feedback. We're basically doing:

Thread thread = new Thread(() => Method());

thread.Start(); // Fire and forget; let the UI thread finish.

If the Gallery Server comes under heavy load, will creating lots of threads like these cause performance issues on the main thread, or am I just being paranoid?

Jan 9, 2011 at 4:08 PM

You're not being paranoid. Creating a thread per download/rating is a very bad idea. Threads have a high runtime cost in creating and destroying them. Too many threads at the same time can degrade overall system performance as the CPU is spending time context switching between them.

This is why the framework has the ThreadPool. I'd change that code to be ThreadPool.QueueUserWorkItem(Method) or equivalent.

Is the download incrementing really that slow that this parallelism is needed? I'm less worried about ratings, more worried about Downloads since we expect that to happen all the time.

Jan 9, 2011 at 5:45 PM

Scott, let's change to the ThreadPool.QueueUserWorkItem method.

We may be guilty of a bit of pre-optimization here. The incrementing probably isn't all that slow, but it does make a few database calls in order to handle the aggregate calculations and update all packages with the same id. Our instinct was it would be better to do that in the background, especially for a gallery like NuGet which will have a pretty high rate of downloads.

Jan 9, 2011 at 6:21 PM

I've gone ahead and made the change. Good thing we abstracted the threaded behavior to its own class. The change was simple. ;)

Jan 9, 2011 at 7:54 PM

Great, I think that's the way to go.  We really want to keep the download path as fast as possible, as there can be multiple downloads during one install from VS, so it's a sensitive code path.