25

Apparently the TaskFactory.StartNew method in .NET 4.0 is intended as a replacement for ThreadPool.QueueUserWorkItem (according to this post, anyway). My question is simple: does anyone know why?

Does TaskFactory.StartNew have better performance? Does it use less memory? Or is it mainly for the additional functionality provided by the Task class? In the latter case, does StartNew possibly have worse performance than QueueUserWorkItem?

It seems to me that StartNew would actually potentially use more memory than QueueUserWorkItem, since it returns a Task object with every call and I would expect that to result in more memory allocation.

In any case, I'm interested to know which is more appropriate for a high-performance scenario.

Dan Tao
  • 119,009
  • 50
  • 280
  • 431

3 Answers3

7

Performance is a ... depends. If you are doing a lot of parallel tasks, then .net 4 tasks will perform better, plus give you more fine grained control (more robust cancellation, ability to wait on multiple tasks simultaneously, ability to create parent/child task relationships, Ability to specify LongRunning, etc.. etc.. etc..)

Additionally, the ability to specify your own TaskScheduler means you can customize it for your needs. The built-in task scheduler is far more multi-core aware than the old ThreadPool.

As for using more memory. Every thread reserves a minimum of 1MB of memory, the tiny amount used to store a task object is inconsequential. I really would think that's the last of your worries.

Roman Starkov
  • 52,420
  • 33
  • 225
  • 300
Erik Funkenbusch
  • 90,480
  • 27
  • 178
  • 274
  • AFAIK default TaskScheduler uses a ThreadPool and there is no difference between them when you want multi-core support. The guy has even made some tests: http://stackoverflow.com/a/5219311/152291 – prostynick Jul 19 '13 at 10:11
6

TaskFactory.StartNew is more appropriate for a high performance scenario.

You gain a productivity benefit by the set of classes in System.Threading.Tasks and the care that went into their design + integration with the parallel loops and options.

You'll also gain a performance benefit because System.Threading.Tasks are built on top of work stealing in the thread pool which is better for locality (when it matters).

-Rick

Rick
  • 3,145
  • 15
  • 17
  • Hi Rick, can you please tell me, when I use Task.Factory.StartNew, does this takes thread from a pool and I have 1 less thread in my pool? Thanks – Michael Samteladze Mar 16 '16 at 09:52
  • 1
    Task.Factory.StartNew will use the .net thread pool so yeah the thread will come from the pool – Rick Mar 16 '16 at 16:53
  • Is there any way to start new thread which will not be taken from thread pool? – Michael Samteladze Mar 17 '16 at 16:52
  • why would you want to do that? – Rick Mar 17 '16 at 22:40
  • I want to start some logging process, after user submits a form and I don't want him to wait until logging is finished. So I start new thread for that purpose and do all logging in background, so main thread is free and user gets response faster. – Michael Samteladze Mar 18 '16 at 13:08
2

Just from the looks of things, the Task classes were designed to work with the new parallel features in .Net 4. It also looks like you can use Action or Action<T> directly when starting/creating a task. This is all 100% conjecture, though, based on poking around the docs :).

ckramer
  • 9,285
  • 1
  • 21
  • 38