为什么在 DataGrid 中刷新 ObservableCollection 很慢
Why is it slow to refresh ObservableCollection in DataGrid
我每秒需要处理 4000 个消息包,总共有 80 个不同的 ID。我有一个DataGrid
。我已将 ObservableCollection
绑定到 DataGrid。我尝试了 2 种方法来刷新 UI 而不会冻结。我都没有成功。
1.Way
如果有来自不同 ID 的消息,我会将其添加到我的 collection。如果来自相同的ID,我删除旧的并获得新的。
if (MessagePacket._jobs.Where(X => X.ID == dataPacket.ID).FirstOrDefault() == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
for (int x = 0; x < MessagePacket._jobs.Count; x++)
{
if (MessagePacket._jobs[x].ID == dataPacket.ID)
{
MessagePacket._jobs.RemoveAt(x);
MessagePacket._jobs.Add(dataPacket);
}
}
}
2.Way
我正在修改数据而不删除它并刷新collection。
注意 :我尝试每 50 毫秒刷新一次 collection,而不是在每次打包之后。还是很慢。
if (MessagePacket._jobs.Where(X => X.ID == dataPacket.ID).FirstOrDefault() == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
for (int x = 0; x < MessagePacket._jobs.Count; x++)
{
if (MessagePacket._jobs[x].ID == dataPacket.ID)
{
MessagePacket._jobs[x].DLC = dataPacket.DLC;
MessagePacket._jobs[x].RTR = dataPacket.RTR;
MessagePacket._jobs[x].IDE = dataPacket.IDE;
MessagePacket._jobs[x].Byte0 = dataPacket.Byte0;
MessagePacket._jobs[x].Byte1 = dataPacket.Byte1;
MessagePacket._jobs[x].Byte2 = dataPacket.Byte2;
MessagePacket._jobs[x].Byte3 = dataPacket.Byte3;
MessagePacket._jobs[x].Byte4 = dataPacket.Byte4;
MessagePacket._jobs[x].Byte5 = dataPacket.Byte5;
MessagePacket._jobs[x].Byte6 = dataPacket.Byte6;
MessagePacket._jobs[x].Byte7 = dataPacket.Byte7;
MessagePacket._jobs[x].Time = DateTime.Now.ToString("HH:mm:ss");
CollectionViewSource.GetDefaultView(MessagePacket._jobs).Refresh();
}
}
}
如何在不冻结 ui 的情况下加快进程。或者你能展示另一种方法吗?从现在开始谢谢你。
这样的事情应该更有效率:
var p = MessagePacket._jobs.FirstOrDefault(x => x.ID == dataPacket.ID);
if (p == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
int i = MessagePacket._jobs.IndexOf(p);
MessagePacket._jobs[i] = dataPacket;
}
你也可以考虑把_jobs
变成一个ObservableDictionary,这样你就可以简单地写
MessagePacket._jobs[dataPacket.ID] = dataPacket;
我每秒需要处理 4000 个消息包,总共有 80 个不同的 ID。我有一个DataGrid
。我已将 ObservableCollection
绑定到 DataGrid。我尝试了 2 种方法来刷新 UI 而不会冻结。我都没有成功。
1.Way
如果有来自不同 ID 的消息,我会将其添加到我的 collection。如果来自相同的ID,我删除旧的并获得新的。
if (MessagePacket._jobs.Where(X => X.ID == dataPacket.ID).FirstOrDefault() == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
for (int x = 0; x < MessagePacket._jobs.Count; x++)
{
if (MessagePacket._jobs[x].ID == dataPacket.ID)
{
MessagePacket._jobs.RemoveAt(x);
MessagePacket._jobs.Add(dataPacket);
}
}
}
2.Way
我正在修改数据而不删除它并刷新collection。
注意 :我尝试每 50 毫秒刷新一次 collection,而不是在每次打包之后。还是很慢。
if (MessagePacket._jobs.Where(X => X.ID == dataPacket.ID).FirstOrDefault() == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
for (int x = 0; x < MessagePacket._jobs.Count; x++)
{
if (MessagePacket._jobs[x].ID == dataPacket.ID)
{
MessagePacket._jobs[x].DLC = dataPacket.DLC;
MessagePacket._jobs[x].RTR = dataPacket.RTR;
MessagePacket._jobs[x].IDE = dataPacket.IDE;
MessagePacket._jobs[x].Byte0 = dataPacket.Byte0;
MessagePacket._jobs[x].Byte1 = dataPacket.Byte1;
MessagePacket._jobs[x].Byte2 = dataPacket.Byte2;
MessagePacket._jobs[x].Byte3 = dataPacket.Byte3;
MessagePacket._jobs[x].Byte4 = dataPacket.Byte4;
MessagePacket._jobs[x].Byte5 = dataPacket.Byte5;
MessagePacket._jobs[x].Byte6 = dataPacket.Byte6;
MessagePacket._jobs[x].Byte7 = dataPacket.Byte7;
MessagePacket._jobs[x].Time = DateTime.Now.ToString("HH:mm:ss");
CollectionViewSource.GetDefaultView(MessagePacket._jobs).Refresh();
}
}
}
如何在不冻结 ui 的情况下加快进程。或者你能展示另一种方法吗?从现在开始谢谢你。
这样的事情应该更有效率:
var p = MessagePacket._jobs.FirstOrDefault(x => x.ID == dataPacket.ID);
if (p == null)
{
MessagePacket._jobs.Add(dataPacket);
}
else
{
int i = MessagePacket._jobs.IndexOf(p);
MessagePacket._jobs[i] = dataPacket;
}
你也可以考虑把_jobs
变成一个ObservableDictionary,这样你就可以简单地写
MessagePacket._jobs[dataPacket.ID] = dataPacket;