Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: How to modify the return type of AsParallel depending on a context?

Tags:

c#

.net

linq

plinq

LINQ's AsParallel returns ParallelQuery. I wonder if it's possible to change this behavior so that I could compare the LINQ statement run with and without parallelism without actually changing the code? This behavior should be similar to Debug.Assert - when DEBUG preprocessor directive is not set, it's optimized out. So I'd like to be able to make AsParallel return the same type without converting it to ParallelQuery.

I suppose I can declare my own extension method (because I can't override AsParallel) and have that preprocessor directive analyzed within it:

    public static class MyExtensions
    {
#if TURN_OFF_LINQ_PARALLELISM
        public static IEnumerable<T> AsControllableParallel<T>(this IEnumerable<T> enumerable)
        {
            return enumerable;
        }
#else
        public static ParallelQuery<T> AsControllableParallel<T>(this IEnumerable<T> enumerable)
        {
            return enumerable.AsParallel();
        }
#endif
    }

I wonder if there is any other way. Am I asking for too much?

like image 348
Schultz9999 Avatar asked Oct 09 '22 13:10

Schultz9999


2 Answers

What about

            var result = 
                source
#if TURN_ON_LINQ_PARALLELISM
                .AsParallel()
#endif
                .Select(value => value.StartsWith("abcd"));
like image 94
George Mamaladze Avatar answered Oct 17 '22 22:10

George Mamaladze


You can create your own extension methods and forward these to the "real" AsParallel method in release builds and use the sequential ones in debug builds. Extension methods are resolved by checking for method in the current namespace and then are the "outer" namespaces searched (instance methods are still preferred).

   class NonParallelQuery 
    {
        IEnumerable _data;
        public NonParallelQuery(IEnumerable data)
        {
            _data = data;

        }
        public IEnumerator GetEnumerator()
        {
            return _data.GetEnumerator();
        }
    }

    static class Extensions
    {
        public static NonParallelQuery AsParallel(this IEnumerable source)
        {
#if DEBUG
            return new NonParallelQuery(ParallelEnumerable.AsParallel(source));
#else
            return new NonParallelQuery(source);
#endif
        }
    }


    public partial class Form1 : Form
    {

        public Form1()
        {
            var data = new string[] { "first", "second" };
            foreach (var str in data.Select(x => x.ToString()).AsParallel())
            {
                Debug.Print("Value {0}", str);
            }
            InitializeComponent();
        }
like image 2
Alois Kraus Avatar answered Oct 17 '22 21:10

Alois Kraus