Delay Task.Factory.StartNew () in Mono / MonoTouch Mode

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"); // Do something Thread.Sleep(2000); // Done ++NumFinished; } private static void Log(string msg) { Console.WriteLine(DateTime.Now.ToString("HH.mm.ss.fff") + ": Thread " + Thread.CurrentThread.ManagedThreadId + ": " + msg); } } 

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.

+6
c # mono
source share
1 answer

So my question is: is this a bug in Mono / MonoTouch?

Not necessary. I suspect that only the thread pool does not want to start more than one new thread every 500 ms. Note that you see that the first task starts almost instantly. It is only after this that you see a delay.

If you use more tasks on .NET 4.5, you'll see something similar, with the exception of the β€œchunks” of threads starting every second.

You may find that calling ThreadPool.SetMinThreads helps, assuming it is available in MonoTouch.

+6
source share

All Articles