AVollane
@AVollane
Начинающий C# разработчик

Как организовать постоянное обновление DataGrid в отдельном потоке?

Здравствуйте! Разрабатываю приложение для просмотра процессов на компьютере и информации о них.
603a917a2156f735641269.png
Но, сразу возникла необходимость в постоянном обновлении DataGrid, чтобы всегда получать актуальную информацию о процессах. Первой идеей было в отдельном потоке каждые две секунды обновлять DataGrid:
Task.Run(() =>
            {
                while (true)
                {
                    // Обновление данных в DataGrid каждые две секунды
                    processesDataGrid.ItemsSource = Process.GetProcesses();
                    Thread.Sleep(2000);
                }
            });

Но, так не получилось. При отладке выбросило исключение InvalidOperationException:
603a9316d2767491456833.png

Нужна помощь. Как организовать постоянное обновление DataGrid в отдельном потоке, чтобы при этом DataGrid был доступен, т.к. планируется добавить возможность выбирать строку из DataGrid и смотреть подробную информацию.
Заранее спасибо!
  • Вопрос задан
  • 747 просмотров
Решения вопроса 1
Casper-SC
@Casper-SC
Программист (.NET)
Как организовать постоянное обновление DataGrid в отдельном потоке, чтобы при этом DataGrid был доступен, т.к. планируется добавить возможность выбирать строку из DataGrid и смотреть подробную информацию.

Нельзя обновлять элементы UI из не UI потока. Можно получать данные в другом потоке, но обновлять UI нужно из UI потока. Я бы просто пробегал по ObservableCollection<{T}>, где T это класс, реализующий интерфейс INotifyPropertyChanged и обновлял нужные объекты уже в UI потоке. Судя по всему, проект не придерживается паттерна MVVM, а лучше бы придерживался.

Список процессов нужно получать как раз в Task.Run(...), а вот вызывать обновление процессов в UI через Dispatcher или SynchronizationContext.

Посмотри мои ответы здесь:
Как осуществить ввод и вывод данных WPF?
Здесь про Task.Delay и вообще цикл в Task.Run Как сделать цикл на основе ответа на Web запрос в C#?
Здесь как перенаправлять выполнение через SynchronizationContext в UI поток С# Taks и Invoke почему то блокируется форма?

Ещё, ожидание в методах, которые запускаются тасками нужно делать через вызов await Task.Delay(...), но точно не через Thread.Sleep(...):
using System;
using System.Threading.Tasks;

namespace Tasks
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Так
            await Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(1000);
                    Console.Write("=");
                }
            });

            // Или так (обрати внимание на Unwrap()) 
            await Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    await Task.Delay(1000);
                    Console.Write("=");
                }
            }).Unwrap();
        }
    }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Jewish_Cat
Увлекаюсь C#
Тут два выхода:
1)сделать бинд datasource на переменную и обновлять эту переменную, тогда не будет проблемы с потоками(нужно использовать MVVM)
2)изменять datasource с помощью dispatcher
Ответ написан
HemulGM
@HemulGM
Delphi Developer, сис. админ
Синхронизировать нужно такие операции
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы