1

私は現在、いくつかのパケットを傍受し、情報に基づいてリストにいくつかの変更/クラスを追加して送信するプログラムを持っています。

私が現在行っているのは、アイテムを追加するときに、追加しているリストをロックして追加することです。ただし、50ミリ秒ごとにリストから情報を取得するPictureBoxがあります。現在、私が行う方法は次のようになります。

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);
    }
}

ご覧のとおり、反復の長さ全体にわたってロックされるため、ペイントが完了するまでパケットハンドラーがブロックされ、サーバーとクライアントの両方で遅延が発生する可能性があります(パケットハンドラーでアイテムを追加または削除する前にロックするため)。私の質問は、リストからすべてのアイテムをロック内の一時リストにコピーしてから、一時リストからロック外にすべてを描画する方が速いでしょうか?主に私の質問は、リストを反復処理する方が速いのか、それともリストをコピーする方が速いのかということです。

4

2 に答える 2

1

リストを反復処理(読み取り専用)しながらアイテムを追加できる独自のリストを実装できます。アイテムを削除する場合にのみ、リストをロックして、リストが繰り返されないようにする必要があります。

もちろん、反復スレッドは、反復する時点で新しいアイテムを認識していません。

利点:

  • リストの容量が変更されていないときにコピーを回避します。変更された場合でも、リーダーは読み取りを終了できます。それが変更された場合でも、リストアイテムを新しい配列にコピーするときにリストをロックする必要があります。
  • 複数のスレッドが反復できるようにします
  • 反復中にリストにアイテムを追加できます

免責事項:これは非常に概念的なものであり、決してテストしないでください

于 2012-10-17T08:06:11.777 に答える
0

ここでは、リストをコピーする方が良いオプションだと思います。

パフォーマンスは大幅に向上しますが、メモリを大量に消費するため、描画後にリストを適切に破棄することで、ある程度まで処理できます。

Station[] stations = Core.Collections.SpaceStations.ToArray();
于 2012-10-17T07:45:23.590 に答える