为什么在 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;