menu

arrow_back How do I update DataGrid data without freezing or overloading?

by
1 vote
Good evening everyone, I am developing a program to view full information about the processes on the computer:
6056500ae65c6610304357.png


The automatic update of the DataGrid is implemented in a separate thread by linking to the Processes property in the view model (trying to stick to MVVM) that implements the INotifyPropertyChanged interface:
public class MainVM : INotifyPropertyChanged
{
public MainVM()
{
// We perform the update operation in a separate thread
Task.Run(() =>
{
// Endless cycle
while (true)
{
Processes = Process.GetProcesses().ToList();
Thread.Sleep(4000); // Updating every 4 seconds
}
});
}
private List<Process> _processes;
public List<Process> Processes
{
get { return _processes; }
set
{
_processes = value;
OnPropertyChanged("Processes");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}


XAML markup for DataGrid:
<DataGrid Name="processesDataGrid" Grid.Row="1" AutoGenerateColumns="False" 
ItemsSource="{Binding Processes, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding MainModule.FileVersionInfo.CompanyName}" Value="Microsoft Corporation">
<Setter Property="Background" Value="HotPink"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
<DataGridTextColumn Header="Name" Binding="{Binding ProcessName}"/>
<DataGridTextColumn Header="Title" Binding="{Binding MainWindowTitle}"/>
<DataGridTextColumn Header="Memory Size" Binding="{Binding PagedMemorySize64}"/>
<DataGridTextColumn Header="Threads count" Binding="{Binding Threads.Count}"/>
<DataGridTextColumn Header="Company" Binding="{Binding MainModule.FileVersionInfo.CompanyName}"/>
<DataGridTextColumn Header="Description" Binding="{Binding MainModule.FileVersionInfo.FileDescription}"/>
<DataGridTextColumn Header="Copyright" Binding="{Binding MainModule.FileVersionInfo.LegalCopyright}"/>
</DataGrid.Columns>
</DataGrid>


The process list is updated every 4 seconds, this is specified in the view model:
while (true)
{
Processes = Process.GetProcesses().ToList();
Thread.Sleep(4000); // Updating every 4 seconds
}

But, the thing is that the application is very slow, and every 4 seconds it hangs. It becomes difficult to use it. Yes, I understand that this is all because of the load, but in the standard Windows Task Manager it still works without freezing. So, I'm looking for a way to make the DataGrid update as smooth as possible.
Thank you in advance.

1 comment

Instead of Thread.Sleep(4000); you should use Task.Delay. Why hang a thread from a thread pool? It doesn't make any sense and there are no benefits.

2 Answers

by
 
Best answer
0 votes
I don't think the dispatcher updates all the data at once, not by event. Make an Observablecollection instead of a List and change the state of a particular object and you won't have to refresh the whole list after 4 seconds
by
0 votes
With the ToList() method you are sucking out all the objects, try manually using Select to take only the ones you need.