@SaimonPhoenix

Как правильно заполнить ObservableCollection в цикле и в потоке?

Есть класс DP:
public class DP
    {
        public string Number { get; set; }
        public string MachineName { get; set; }
        public string UserName { get; set; }
        public string IPAddress { get; set; }
    }

Коллекция oCollectDP:
ObservableCollection<DP> oCollectDP = new ObservableCollection<DP>();


Метод в котором происходит заполнение:
foreach (var item in lstWorkStation) //Список List<string>lstWorkStation
            {
                DP dp = new DP();
                string compName;
                new Thread(()=>
                {
                    compName = item;
                    dp.Number = oCollectDP.Count().ToString();
                    dp.MachineName = compName;
                    dp.UserName = getUserNameWMI(compName);
                    dp.IPAddress = getUserIP(compName);
                    
                    Dispatcher.Invoke(new Action(() =>oCollectDP.Add(dp)));
                }).Start();
            }


Коллекция заполняется, но некорректно (т.е дублируются записи в полях dp.UserName или dp.IPAddress). Как это исправить?
  • Вопрос задан
  • 977 просмотров
Пригласить эксперта
Ответы на вопрос 3
ImmortalCAT
@ImmortalCAT
C# loving
посмотри методы getUserNameWMi и getUserIP
и зачем поток тебе?
тем более процесс создания потока ресурсоёмкий и не сразу создается в пуле потоков.
попробуй async/await
но точно убери создание потоков
потоки хороши если в них необходимо использовать мат решения, которые зафризят GUI или основной поток.
1. убери создание потоков
2. просмотри методы getUserNameWMI getUserIP
Ответ написан
@SaimonPhoenix Автор вопроса
Решил сделать так:
Parallel.ForEach(lstWorkStation, currItem =>
            { 
                DP dp = new DP();

                dp.Number = oCollectDP.Count.ToString();
                dp.MachineName = currItem;
                dp.UserName = getUserNameWMI(currItem);
                dp.IPAddress = getUserIP(currItem);

                Dispatcher.Invoke(new Action(() =>
                {
                    oCollectDP.Add(dp);
                    (sender as BackgroundWorker).ReportProgress(i);
                }));
                i++;
            });

Корректно ли это?
Ответ написан
Комментировать
@Hydro
C#/.NET Developer
new Thread().Start() здесь лишний.
i++ нигде не юзается.

Dispatcher.Invoke(new Action(() =>
{
if (oCollectDP.Any(e => e.UserName != dp.UserName && e.IpAddress != dp.IpAddress )) // чтобы избежать дублирования
oCollectDP.Add(dp);
(sender as BackgroundWorker).ReportProgress(i);
}));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы