C# 更快地锁定列表<;T>;在迭代或克隆过程中

C# 更快地锁定列表<;T>;在迭代或克隆过程中,c#,locking,gdi+,C#,Locking,Gdi+,我目前有一个程序,可以截取一些数据包,根据信息修改/向列表中添加类,然后发送 我现在做的是当我添加一个项目时,我会在添加它的同时锁定我要添加的列表。然而,我有一个PictureBox,每隔50毫秒左右从列表中提取信息。目前我的做法如下: Graphics g = e.Graphics; lock (Core.Collections.SpaceStations) { foreach (Classes.Station station in Core.Collections.SpaceSta

我目前有一个程序,可以截取一些数据包,根据信息修改/向列表中添加类,然后发送

我现在做的是当我添加一个项目时,我会在添加它的同时锁定我要添加的列表。然而,我有一个PictureBox,每隔50毫秒左右从列表中提取信息。目前我的做法如下:

Graphics g = e.Graphics;

lock (Core.Collections.SpaceStations)
{
    foreach (Classes.Station station in Core.Collections.SpaceStations)
    {
        Image img;
        switch (station.Company)
        {
            case 1:
                img = Prog.Properties.Resources.mmo_station;
                break;
            case 2:
                img = Prog.Properties.Resources.eic_station;
                break;
            case 3:
                img = Prog.Properties.Resources.vru_station;
                break;
            default:
                img = new Bitmap(50, 50);
                break;
        }
        g.DrawImage(img, (float)((station.Position.x - 750) / Core.CurrentMap.ByX), (float)((station.Position.y - 750) / Core.CurrentMap.ByY), 35, 35);
    }
}

正如您所看到的,它会锁定整个迭代长度,这会导致我的数据包处理程序阻塞,直到它完成绘制,并会导致服务器和客户端的延迟(因为我在添加或删除数据包处理程序中的项之前锁定)。我的问题是,将列表中的所有项目复制到锁内的临时列表中,然后从临时列表中将它们全部绘制到锁外会更快吗?我的主要问题是,迭代列表还是复制列表更快。

我认为复制列表是更好的选择

它无疑会提高性能,但会占用大量内存,可以通过在绘制后正确处理列表来在一定程度上处理这些内存

Station[] stations = Core.Collections.SpaceStations.ToArray();

我认为复制列表是更好的选择

它无疑会提高性能,但会占用大量内存,可以通过在绘制后正确处理列表来在一定程度上处理这些内存

Station[] stations = Core.Collections.SpaceStations.ToArray();

您可以实现自己的列表,该列表允许您在迭代(只读)列表时添加项目。只有在删除项目时,才需要锁定列表,以防止重复访问它

当然,您的迭代线程在迭代时并不知道新项目

好处:

  • 避免在列表容量不变的情况下复制,如果列表容量发生变化,则读者仍可完成阅读。如果更改,则在将列表项复制到新数组时仍需要锁定列表
  • 允许多个线程迭代
  • 允许在迭代时向列表中添加项

免责声明:这是非常概念化的,永远不要测试它

您可以实现自己的列表,它允许您在迭代(只读)列表时添加项目。只有在删除项目时,才需要锁定列表,以防止重复访问它

当然,您的迭代线程在迭代时并不知道新项目

好处:

  • 避免在列表容量不变的情况下复制,如果列表容量发生变化,则读者仍可完成阅读。如果更改,则在将列表项复制到新数组时仍需要锁定列表
  • 允许多个线程迭代
  • 允许在迭代时向列表中添加项

免责声明:这是非常概念化的,永远不要测试它

好吧,toarray很有趣。它是否比
List tempStation=new List()有性能优势;tempStation.AddRange(Core.Collections.SpaceStations)因为你只是从列表中读取,没有添加任何内容,所以你不需要“列表”。好吧,是的,这很有意义。所以它确实有性能优势?还有,你会如何“妥善处理”?好吧,今天的聚会很有趣。它是否比
List tempStation=new List()有性能优势;tempStation.AddRange(Core.Collections.SpaceStations)因为你只是从列表中读取,没有添加任何内容,所以你不需要“列表”。好吧,是的,这很有意义。所以它确实有性能优势?另外,您将如何“正确处理它”?听起来很有趣,我会看看我能想出什么。@jduncanator如果有效,给我反馈:-)添加了关于添加项目的更多信息。有趣的是,我会看看我能想出什么。@jduncanator如果有效,给我反馈:-)添加了关于添加项目的更多信息