【发布时间】:2021-12-23 08:17:45
【问题描述】:
下午好。 帮助解决以下问题。 如果我为 DataGrid.ItemsSource 设置了一些 DataTable,我将在另一个线程中对其进行更新,然后定期调用 DataGrid.Items.Refresh() 我会有内存泄漏。 有没有办法避免这种情况?
<Window x:Class="TestDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestDataGrid"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<DataGrid x:Name="DataGrid1" d:ItemsSource="{d:SampleData ItemCount=5}" Grid.ColumnSpan="2"/>
</Grid>
</Window>
主窗口
using System;
using System.Windows;
namespace TestDataGrid
{
public partial class MainWindow : Window
{
DataWorker data = new DataWorker();
public MainWindow()
{
InitializeComponent();
DataGrid1.ItemsSource = data.dt.DefaultView;
data.DataChanged += OnDataChanged;
data.RunThread();
}
private void OnDataChanged(object obj, EventArgs e)
{
Dispatcher.Invoke(new Action(() =>
{
DataGrid1.Items.Refresh();
//this.Title = data.dt.Rows[0].ItemArray[0].ToString();
}));
}
}
}
DataWorker.cs
using System;
using System.Data;
using System.Threading;
namespace TestDataGrid
{
internal class DataWorker
{
public event EventHandler DataChanged;
public DataWorker()
{
column.DataType = Type.GetType("System.UInt64");
column.ColumnName = "DATA";
dt.Columns.Add(column);
}
public DataTable dt = new DataTable();
private DataColumn column = new DataColumn();
public void RunThread()
{
Thread th = new Thread(DataChange);
th.Start();
}
private void DataChange()
{
while (true)
{
dt.Clear();
dt.Rows.Add(new object[] { DateTime.Now.Ticks });
DataChanged?.Invoke(this, EventArgs.Empty);
Thread.Sleep(1000);
}
}
}
}
如果我将 DataGrid1.Items.Refresh() 更改为 this.Title = data.dt.Rows[0].ItemArray[0].ToString() 为例,然后内存OK。
项目:GitHub
【问题讨论】:
-
这在我看来不像是内存泄漏。这看起来像是 .NET 的正常(如果激进)内存使用量,这是由其每 CPU 核心 GC 堆引起的。你的机器有多少个 CPU 内核?
-
我在 i7-1165G7 上运行 4 核。
-
如今几乎没有使用 thread.sleep 的好理由。请改用 await task.delay(n) 。并调用异步。我认为真正的事情是做一些更复杂的事情。您是否考虑过行视图模型的可观察集合而不是数据表?除非您的所有数据每秒都完全更改,否则识别更改的属性并仅在现有视图模型中更改它们是很常见的。一个相当普遍的要求是用不同的背景颜色突出显示变化。