In Mono and MonoTouch, I see about a 500 millisecond delay between when I call:
StartNew(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler);
and when the working code actually starts execution.
I created a test to show this:
public static class TestTaskFactory { private class TaskInfo { public int Number; } private static int NUM_TASKS = 5; private static int NumFinished = 0; public static void Run() { for (int n = 1; n <= NUM_TASKS; n++) { Log("Starting task #" + n + " ..."); var task_info = new TaskInfo { Number = n }; var task = Task.Factory.StartNew(Worker, task_info, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); Thread.Sleep(0); } Log("Waiting for tasks to finish ..."); while (NumFinished < NUM_TASKS) { Thread.Sleep(1); } Log("All done"); } private static void Worker(object state) { var task_info = (TaskInfo)state; Log("Task #" + task_info.Number + " running");
Output in Mono on Mac:
16.57.31.420: Thread 1: Starting task #1 ... 16.57.31.508: Thread 1: Starting task #2 ... 16.57.31.508: Thread 1: Starting task #3 ... 16.57.31.508: Thread 1: Starting task #4 ... 16.57.31.508: Thread 1: Starting task #5 ... 16.57.31.508: Thread 1: Waiting for tasks to finish ... 16.57.31.510: Thread 5: Task #1 running 16.57.32.009: Thread 6: Task #2 running <-- Approx 500 msec later 16.57.32.511: Thread 7: Task #3 running <-- Approx 500 msec later 16.57.33.012: Thread 8: Task #4 running <-- Approx 500 msec later 16.57.33.513: Thread 9: Task #5 running <-- Approx 500 msec later 16.57.35.515: Thread 1: All done
As if Mono wants to wait up to 500 ms to reuse an existing stream before splitting a new one. If I reduce the working time below 500 ms, the delay will decrease. For example, changing the working Thread.Sleep (2000) to Thread.Sleep (50):
... 17.13.20.262: Thread 5: Task #1 running 17.13.20.314: Thread 5: Task #2 running <-- approx 50 msec later 17.13.20.365: Thread 5: Task #3 running <-- approx 50 msec later 17.13.20.416: Thread 5: Task #4 running <-- approx 50 msec later 17.13.20.466: Thread 5: Task #5 running <-- approx 50 msec later
But in MS Framework 4.0 there is no big delay before running the working code:
... 17.05.42.238: Thread 9: Waiting for tasks to finish ... 17.05.42.256: Thread 11: Task #1 running 17.05.42.256: Thread 12: Task #3 running <-- little delay 17.05.42.256: Thread 13: Task #4 running <-- little delay 17.05.42.257: Thread 10: Task #2 running <-- little delay 17.05.43.264: Thread 14: Task #5 running <-- little delay
Before I submit a bug report to Mono, I wanted to check my sanity that I was missing some of the settings that I need to make on Mono or use Task.Factory incorrectly. I actually use max concurrency scheduler in my real application.
So my question is: is this a bug in Mono / MonoTouch?
Update: I switched from using ThreadPool in Mono * to the Ami Bar Smart Thread Pool ( github ; code project article ). GSerjo Extended Thread Pool also looked good, but had a lot of dependencies that I tried to avoid on mobile devices. I wrote some of my simple tests in the Xamarim thread . I probably missed 100 other thread pool implementations, but so far I'm happy with SmartThreadPool. Use WINDOWS_PHONE mode to compile to MonoTouch.