I am not sure why you are seeing no task running. Are you sure your Task.Run()
is being hit? That is to say is i < symbols.Result.Count()
satisfied?
Regardless of the above, let us try and achieve what you want. Firstly, no, it is not correct to say that because your machine has four physical cores/'threads', that you can use a maximum of four Thread
s. These are not the same things. A Google on this subject will bring a plethora of information your way about this.
Basically starting a thread the way you have will start background threads on a thread pool, and this thread pool can hold/govern numerous threads see Threading in C# by J. Albahari for more information. Whenever you start a thread, a few hundred microseconds are spent organizing such things as a fresh private local variable stack. Each thread also consumes (by default) around 1 MB of memory. The thread pool cuts these overheads by sharing and recycling threads, allowing multithreading to be applied at a very granular level without a performance penalty. This is useful when leveraging multicore processors to execute computationally intensive code in parallel in “divide-and-conquer” style.
The thread pool also keeps a lid on the total number of worker threads it will run simultaneously. Too many active threads throttle the operating system with administrative burden and render CPU caches ineffective. Once a limit is reached, jobs queue up and start only when another finishes.
Okay, now for your code. Let us say we have a list of stock types
List<string> types = new List<string>() { "AMEX", "AMEC", "BP" };
To dispatch multiple threads to do for for each of these (not using async
/await
), you could do something like
foreach (string t in types)
{
Task.Factory.StartNew(() => DoSomeCalculationForType(t));
}
This will fire of three background thread pool threads and is non-blocking, so this code will return to caller almost immediately.
If you want to set up post processing you can do this via continuations and continuation chaining. This is all described in the Albahari link I provided above.
I hope this helps.
--
Edit. to address comments:
Beginning with the .NET Framework version 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. A process can call the GetMaxThreads method to determine the number of threads.
However, there's something else at play: the thread pool doesn't immediately create new threads in all situations. In order to cope with bursts of small tasks, it limits how quickly it creates new threads. IIRC, it will create one thread every 0.5 seconds if there are outstanding tasks, up to the maximum number of threads. I can't immediately see that figure documented though, so it may well change. I strongly suspect that's what you're seeing though. Try queuing a lot of items and then monitor the number of threads over time.
Basically let the thread pool dispatch what it wants, its optimizer will do the best job for your circumstance.