3

I will use "Process" to refer to the work that is going to happen in parallel, and "enqueue" to refer to whatever process is going to be used to initiate that process (whether that be Task.Run, ThreadPool.QUWI, new Thread() ... whatever).

We have a performance sensitive program that spawn multiple parallel processes to gather data.

We're having issues with the spawning, that the processes are not beginning immediately.

Specifically, if we prepare a process, start a timer, enqueue the process, and check the timer as the very first action in the process ... then we see that the time delay occasionally stretches into 100s or even 1000s of milliseconds.

Given that the process itself is supposed to only run for 3-10 seconds, having a 2sec delay between enqueuing and activation of the process is a major issue.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Currently our implementations started using TP.QUWI, and then we move to using Task.Run. Our initial investigation lead us to the Thread-Creation-Strategy used by Threadpool and using ThreadPool.SetMinThreads(), so we're pursuing that angle, to see if that will completely resolve the issue.

But is there another change/approach that we should be looking at, if our goal is to have the process start immediately after enqueuing?

svick
  • 236,525
  • 50
  • 385
  • 514
Brondahl
  • 7,402
  • 5
  • 45
  • 74
  • Does your application use `ThreadPool` extensively for other "processes" that are not time-sensitive? Why is the timing so important for you? – svick May 11 '16 at 18:08
  • I don't understand the questions, @svick? Yes, we also use `ThreadPool` for some background tasks that aren't in the perf-critical paths, but I don't see the relevance. And like I said ... the program is performance sensitive ... I don't see why the reasons for that being true would matter? – Brondahl May 13 '16 at 09:18

1 Answers1

1

Taken from here (I strongly suggest you have a read up):

Seems as though what you want can be achieved by overridding the default task scheduler.... scarey...

You can't assume that all parallel tasks will immediately run. Depending on the current work load and system configuration, tasks might be scheduled to run one after another, or they might run at the same time. For more information about how tasks are scheduled, see the section, "The Default Task Scheduler," later in this chapter.

Creating Tasks with Custom Scheduling

You can customize the details of how tasks in .NET are scheduled and run by overriding the default task scheduler that's used by the task factory methods. For example, you can provide a custom task scheduler as an argument to one of the overloaded versions of the TaskFactory.StartNew method.

There are some cases where you might want to override the default scheduler. The most common case occurs when you want your task to run in a particular thread context... Other cases occur when the load-balancing heuristics of the default task scheduler don't work well for your application. For more information, see the section, "Thread Injection," later in this chapter.

Unless you specify otherwise, any new tasks will use the current task scheduler...

You can implement your own task scheduler class. For more information, see the section, "Writing a Custom Task Scheduler," later in this chapter.

Thread Injection

The .NET thread pool automatically manages the number of worker threads in the pool...

Have a read of this SO post "replacing the task scheduler in c sharp with a custom built one"

Community
  • 1
  • 1
Paul Zahra
  • 9,522
  • 8
  • 54
  • 76
  • I see very little benefits to this rather complicated approach compared to just starting threads explicitly: the overhead of thread creation is negligible when talking about 10 seconds work and the custom solution would be non trivial if it wanted to reuse threads. The task interface is useful, but a little wrapper can still expose the work as a task. – Voo May 11 '16 at 14:33