5

I have a code base using ThreadPool.QueueUserWorkItem in several places. I thought it would be a good idea to switch from using ThreadPool.QueueUserWorkItem to using Task.Factory.StartNew with TaskScheduler.Default as a scheduler.

After upgrading, I saw execution times of the application to sky high. It as an online transnational application, receiving requests and typically responding between 40ms and 500ms which is acceptable. After the switch to the Tasks way, I see many transactions taking from 4000ms to even 38000ms to respond which is unacceptable.

The flow is pretty complex. It involves a synchronous loop for the incoming transactions, which actually does the simple validations and insert to the database. After that, some parallel actions are fired, and the main loop continues to the next incoming transaction. The parallel actions are mainly logging, and a db intensive quality check of the data.

All logging actions were initiated in the ThreadPool with

ThreadPool.QueueUserWorkItem(/*logging action*/)

The quality check action was initiated with

Task.Factory.StartNew(/*qc action*/,
     TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness)

After applying the changes The logging actions were switched to

Task.Factory.StartNew(/*logging action*/,
     CancellationToken.None,
     TaskCreationOptions.None,
     TaskScheduler.Default)

And the quality check action was switched to

Task.Factory.StartNew(/*qc action*/,
     CancellationToken.None,
     TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness,
     TaskScheduler.Default)

Is there a possibility that the logging actions are stalling the quality check action when executed with Task.Factory.StartNew on the ThreadPoolScheduler (TaskScheduler.Default) but when executed directly on ThreadPool with QueueUserWorkItem, they don't?

Is there a possibility that the TaskCreationOptions.PreferFairness flag in the quality check action, makes quality check wait for the logging actions even when this flag is not set in their initiation?

Thanasis Ioannidis
  • 2,981
  • 1
  • 30
  • 50
  • The performance difference is unimportant (and neglibile). Any difference encountered is probably caused by the *rest* of the code. The *big* difference is that using the thread pool directly prevents you from composing asynchronous actions, using any kind of buffering etc. You should probably be looking at ActionBlock – Panagiotis Kanavos Apr 25 '16 at 13:36
  • PS. Looks like someone missed the last .NET meetup where we discussed this very topic – Panagiotis Kanavos Apr 25 '16 at 13:36
  • PPS. Tasks use the ThreadPool too. 4 - 38 seconds delay is probably caused by locks eg on the file. You'd have to post the rest of the code to debug this. – Panagiotis Kanavos Apr 25 '16 at 13:40
  • 1
    Finally, .NET 4.0 is no longer supported or needed, as the only OS that required it (XP) is also unsupported. In fact, given that all payment and most other web service providers require TLS1.1, .NET 4.5.2 is a *minimum* requirement – Panagiotis Kanavos Apr 25 '16 at 13:47
  • 1
    @PanagiotisKanavos Note that if you use `TaskCreationOptions.LongRunning` then current implementations will create a new thread for the task rather than using a threadpool thread. – Matthew Watson Apr 25 '16 at 13:51
  • @MatthewWatson actually, it's a suggestion to the TaskScheduler to do so. That *won't* cause a multi-secod delay though. I'd look to thrashing, in-process locks and database blocking for the culprit. Disabling the connection pool or using long-lived connections can lead to blocking. – Panagiotis Kanavos Apr 25 '16 at 13:56
  • I'd try turning off `PreferFairness` - it might not be appropriate for your scenario. [See here for details](http://blogs.msdn.com/b/pfxteam/archive/2009/07/07/9822857.aspx) – Matthew Watson Apr 25 '16 at 13:57
  • @MatthewWatson in fact, the only real solution is to *simplify* the flow, not try to fiddle with the task parameters. Caching of lookup data and throttling the number of concurrent connections can result in huge benefites. The TPL Dataflow was created for this specific scenario – Panagiotis Kanavos Apr 25 '16 at 13:57
  • @ThanasisIoannidis, if you have an ETL scenario and use SQL Server, why don't you use SSIS? – Panagiotis Kanavos Apr 25 '16 at 13:59

0 Answers0