A
A
Anton Baryshev2021-02-27 21:47:15
.NET
Anton Baryshev, 2021-02-27 21:47:15

How to organize constant updating of DataGrid in a separate thread?

Hello! I am developing an application for viewing processes on a computer and information about them.
603a917a2156f735641269.png
But, immediately there was a need to constantly update the DataGrid in order to always receive up-to-date information about the processes. The first idea was to update the DataGrid in a separate thread every two seconds:

Task.Run(() =>
            {
                while (true)
                {
                    // Обновление данных в DataGrid каждые две секунды
                    processesDataGrid.ItemsSource = Process.GetProcesses();
                    Thread.Sleep(2000);
                }
            });

But, it didn't work out that way. While debugging, I threw an InvalidOperationException:
603a9316d2767491456833.png

Need help. How to organize a constant update of the DataGrid in a separate thread, so that the DataGrid is available, because it is planned to add the ability to select a row from the DataGrid and view detailed information.
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
B
Boris the Animal, 2021-02-28
@AVollane

How to organize a constant update of the DataGrid in a separate thread, so that the DataGrid is available, because it is planned to add the ability to select a row from the DataGrid and view detailed information.

You cannot update UI elements from a non-UI thread. You can get data on another thread, but you need to update the UI from the UI thread. I would simply run through ObservableCollection<{T}> where T is a class that implements the INotifyPropertyChanged interface and update the necessary objects already on the UI thread. Apparently, the project does not adhere to the MVVM pattern, but it would be better if it did.
You need to get the list of processes just in Task.Run(...), but call the process update in the UI via Dispatcher or SynchronizationContext.
See my answers here :
How to handle WPF input and output?
Here about Task.Delay and in general a loop in Task.Run How to make a loop based on the response to a Web request in C#?
Here's how to redirect execution via SynchronizationContext to UI threadС# Taks and Invoke why is the form blocked?
Also, waiting in methods that are launched by tasks should be done through the call await Task.Delay(...), but definitely not through 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();
        }
    }
}

V
Vladislav, 2021-02-27
@Jewish_Cat

There are two ways out:
1) make a datasource bind to a variable and update this variable, then there will be no problem with threads (you need to use MVVM)
2) change the datasource using the dispatcher

H
HemulGM, 2021-02-27
@HemulGM

You need to synchronize such operations

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question