LINQ: Как изменить тип возвращаемого значения AsParallel в зависимости от контекста? - PullRequest
5 голосов
/ 08 ноября 2011

LINQ AsParallel возвращает ParallelQuery.Интересно, возможно ли изменить это поведение, чтобы я мог сравнить оператор LINQ, выполняемый с параллелизмом и без него без фактического изменения кода?Это поведение должно быть похоже на Debug.Assert - когда директива препроцессора DEBUG не установлена, она оптимизируется.Поэтому я бы хотел, чтобы AsParallel возвращал тот же тип без преобразования в ParallelQuery.

Полагаю, я могу объявить свой собственный метод расширения (поскольку я не могу переопределить AsParallel) и проанализировать в нем директиву препроцессора:

    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
    }

Интересно, есть ли какой-нибудьдругой путь.Я спрашиваю слишком много?

Ответы [ 2 ]

2 голосов
/ 08 ноября 2011

А как же

            var result = 
                source
#if TURN_ON_LINQ_PARALLELISM
                .AsParallel()
#endif
                .Select(value => value.StartsWith("abcd"));
2 голосов
/ 08 ноября 2011

Вы можете создавать свои собственные методы расширения и пересылать их «реальному» методу AsParallel в сборках выпуска и использовать последовательные в сборках отладки.Методы расширения разрешаются путем проверки метода в текущем пространстве имен, а затем выполняется поиск «внешних» пространств имен (методы экземпляра по-прежнему предпочтительны).

   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();
        }
...