This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 8559 - TaskScheduler passed with parallel options to Parallel.ForEach not used correctly
Summary: TaskScheduler passed with parallel options to Parallel.ForEach not used corre...
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: CORLIB (show other bugs)
Version: 2.10.x
Hardware: PC All
: --- normal
Target Milestone: ---
Assignee: Jérémie Laval
URL:
Depends on:
Blocks:
 
Reported: 2012-11-22 12:22 UTC by Karol Gwaj
Modified: 2012-11-26 07:15 UTC (History)
2 users (show)

See Also:
Tags:


Attachments

Description Karol Gwaj 2012-11-22 12:22:00 UTC
Looks like Parallel.ForEach is not using task scheduler passed with parallel options to create its own tasks,
It is setting correctly TaskScheduler.Current property of child tasks, but besides that it should also use it itself to create this tasks. 

So to "trick" it to use my custom TaskScheduler (which increases MaximumConcurrencyLevel) i have to wrap it into additional task and run it synchronously:

		public static void Main (string[] args)
		{
            ThreadPool.SetMaxThreads(100, 100);
            ThreadPool.SetMinThreads(100, 100);
			Console.WriteLine(TaskScheduler.Current.GetType());
			
            var task = new Task(delegate()
            {
				    Console.WriteLine(TaskScheduler.Current.GetType());
			        Parallel.ForEach(new[] { 1, 2, 3,4, 5, 6,7, 8, 9, 0, 1, 2 ,3, 4, 5 }, new ParallelOptions() { MaxDegreeOfParallelism = 100 }, i =>
                    {
                        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(5000);
                    });                
            });

            task.RunSynchronously(SimpleTaskScheduler.Default);


			Console.ReadKey();
		}
Comment 1 Karol Gwaj 2012-11-26 05:19:09 UTC
Line below (346) is the "bad boy" here:

int num = Math.Min (GetBestWorkerNumber(), options != null && options.MaxDegreeOfParallelism != -1 ? options.MaxDegreeOfParallelism : int.MaxValue);


GetBestWorkerNumber() method is using TaskScheduler from current context instead of the one passed with options. Instead it should look more or less like that:

int num = Math.Min ((options != null) && (options.TaskScheduler != null) ? options.TaskScheduler.MaximumConcurrencyLevel : GetBestWorkerNumber(), options != null && options.MaxDegreeOfParallelism != -1 ? options.MaxDegreeOfParallelism : int.MaxValue);
Comment 2 Jérémie Laval 2012-11-26 07:15:16 UTC
Thanks for the report. Fixed in mono-2-10 and master.

Note You need to log in before you can comment on or make changes to this bug.