Список разделяй и властвуй - проход по значению или по ссылке - PullRequest
1 голос
/ 24 марта 2011

Я не на .NET 4.

Я получаю огромный список из источника данных.Когда количество элементов в списке больше, чем X, я хочу разделить список, назначить каждому разделу поток.после обработки разделов мне нравится объединять их.

            var subsets = list.PartitionEager(50000);

            //var subsets = list.Partition<T>(50000);

            Thread[] threads = new Thread[subsets.Count()];
            int i = 0;
            foreach (var set in subsets)
            {
                threads[i] = new Thread(() => Convertor<T>(set));
                threads[i].Start();
                i++;
            }

            for (int j = 0; j < i; j++)
            {
                threads[j].Join();
            }

Метод конвертора - это статический метод, который принимает список и выполняет поиск.

   public static void Convertor<T>(List<T> list) where T : IInterface        {

        foreach (var element in list)
        {
            **// do some lookup and assing a value to element
            // then do more lookup and assign a value to element**
        }

    }

Когда я запускаю этот код, даже еслия знаю, что большинству элементов будет присвоено значение.Они фактически возвращаются к нулю.

Я знаю, что копия списка будет передана методу, но любое изменение элемента должно быть отражено в верхнем методе.однако это происходит только в последнем подмножестве.

Я даже добавил некоторый код для объединения списков в один.

                list.Clear();

                foreach (var set in subsets)
                {
                    list.AddRange(set);
                }

код для разделения:

    public static List<List<T>> PartitionEager<T>(this List<T> source, Int32 size)
    {
        List<List<T>> merged = new List<List<T>>();
        for (int i = 0; i < Math.Ceiling(source.Count / (Double)size); i++)
        {
            merged.Add(new List<T>(source.Skip(size * i).Take(size)));
        }

        return merged;
    }

Что я делаю не так?как решить эту проблему?id как элементы, которым будут присвоены значения после поиска?это связано с синхронизацией или передачей параметров?

Ответы [ 2 ]

3 голосов
/ 24 марта 2011

Если .NET 4 является опцией, вы можете просто использовать Parallel.For или Parallel.ForEach .Эти методы автоматически обрабатывают разделение для вас, а также предоставляют множество других преимуществ с точки зрения масштабируемости для нескольких степеней параллелизма в разных системах.

2 голосов
/ 24 марта 2011

Похоже, у вас modified closure при создании темы.Если я прав, то все ваши темы обновляют один и тот же (последний) набор.Измените код следующим образом:

        foreach (var set in subsets)
        {
            var setLocalCopy = set;
            threads[i] = new Thread(() => Convertor<T>(setLocalCopy));
            threads[i].Start();
            i++;
        }
...