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
: TaskScheduler passed with parallel options to Parallel.ForEach not used corre...
Status: RESOLVED FIXED
Product: Class Libraries
Classification: Mono
Component: CORLIB
: 2.10.x
: PC All
: --- normal
: ---
Assigned To: Jérémie Laval
:
:
:
:
  Show dependency treegraph
 
Reported: 2012-11-22 12:22 EST by Karol Gwaj
Modified: 2012-11-26 07:15 EST (History)
2 users (show)

See Also:
Tags:
Test Case URL:
External Submit: ---


Attachments

Description Karol Gwaj 2012-11-22 12:22:00 EST
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 EST
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 EST
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.