質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2743閲覧

C#、OutOfMemoryExceptionが発生する(DXF読み込み)

ElecDove

総合スコア254

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/04/14 19:29

いつもお世話になっております。

C#を使ってDXFの読み込み(パース?)をしたいと考えているのですが、
大量のエンティティ(線分、円弧等)を読み込んでいるためか、
OutOfMemoryExceptionが発生してしまいます

おそらく、根本的な作り方に問題があると思うのでどのような方向性で設計していけば数千~数万のエンティティをメモリ上に保持しても大丈夫か教えていただきたいです

(VSのデバッグ画面にある診断ツールでは、ちょっと大きなDXFファイルを読み込むとメモリ使用量が1GBをあっという間に超えてしまいます)

現在のコーディングでは、
あらかじめDXFの内部構造(に近い)の形をしたクラスをひな型として、
ファイルを読み込みながらそのひな型に実際のデータを肉付けしていく形にしています。

長いですが一応ひな型を示します。
あまりこのあたりの構造がよくわかっていないので意味不明なことになっているかもしれませんがご容赦ください
OutOfMemoryとは関係ない内容でも、アドバイスいただけると助かります。

変数の命名がアッパーだったりロワーだったりするのはまだあまり慣れてないからですすいません、、、少しずつ直していきます

C#

1 private class DxfFormat { 2 public enum SectionIdList { 3 HEADER, 4 TABLES, 5 BLOCKS, 6 ENTITIES 7 }; 8 9 public HeaderClass Header = new HeaderClass(); 10 public class HeaderClass { 11 public enum VersionList { AC1003, AC1006, AC1009, AC1012, AC1014, AC1015, OTHER }; 12 public VersionList Version = VersionList.OTHER; 13 14 public Point extmin = new Point(); //オブジェクト(図形)の最小値 15 public Point extmax = new Point(); //オブジェクト(図形)の最大値 16 public Point limmin = new Point(); //図面の最小値 17 public Point linmax = new Point(); //図面の最大値 18 public int dimscale; //寸法の尺度 19 public int PEXTMIN; //ペーパー空間のオブジェクトの最小値 20 public int PEXTMAX; //ペーパー空間のオブジェクトの最大値 21 public int DWGCODEPAGE; //図面のコードページ日本語はR13Jまで "dos932"、R14から"ANSI_932"です。 22 } 23 public TableClass table = new TableClass(); 24 public class TableClass { 25 26 public class LineType { 27 public string Name; 28 public string Description; 29 } 30 31 public List<LineType> LineTypeList = new List<LineType>(); 32 public int numOfLayer; 33 public string[] LayerName = new string[256]; 34 public int numOfLine; 35 } 36 37 public List<EntityClass> Entity = new List<EntityClass>(); 38 public class EntityClass { 39 40 public EntityClassLine Line; 41 public class EntityClassLine { 42 public PointF Start = new PointF(); 43 public PointF End = new PointF(); 44 } 45 46 public EntityClassArc Arc; 47 public class EntityClassArc { 48 public PointF Center = new PointF(); 49 public float Radius; 50 public float StartDegree; 51 public float EndDegree; 52 } 53 54 public EntityClassCircle Circle; 55 public class EntityClassCircle { 56 public PointF Center = new PointF(); 57 public float Radius; 58 } 59 60 public enum EntityList { 61 /// <summary> 62 /// 直線要素 63 /// </summary> 64 LINE, 65 /// <summary> 66 /// 円要素 67 /// </summary> 68 CIRCLE, 69 /// <summary> 70 /// 円弧 71 /// </summary> 72 ARC, 73 /// <summary> 74 /// 点 75 /// </summary> 76 POINT, 77 /// <summary> 78 /// 文字列 79 /// </summary> 80 TEXT 81 }; 82 /// <summary> 83 /// その図形の種類(線分/円/点…etc...) 84 /// </summary> 85 public EntityList Entity; 86 /// <summary> 87 /// その図形の描かれるレイヤー番号 88 /// </summary> 89 public string LayerName; 90 /// <summary> 91 /// その図形の描かれている色 92 /// </summary> 93 public int ColorName; 94 /// <summary> 95 /// その図形の描かれる線種 96 /// </summary> 97 public string LineType; 98 } 99 }

実際のファイル読み込み、解析処理は次のようになっています
(例として、ファイル中からLINEを見つけた後の処理のみ記載します)

C#

1//まずは、様々なエンティティを格納するオブジェクトを作って 2DxfFormat.EntityClass ent = new DxfFormat.EntityClass(); 3 4 if (DxfRaws[i].s == "LINE") { 5 i++; 6 //今回はその中でも「線分」なので線分のインスタンスを作って 7 ent.Entity = DxfFormat.EntityClass.EntityList.LINE; 8 ent.Line = new DxfFormat.EntityClass.EntityClassLine(); 9 //開始点、終了点などの図形的情報を抽出、メンバに代入 10 while (DxfRaws[i].groupCode != 0) { 11 if (DxfRaws[i].groupCode == 6) { 12 ent.LineType = DxfRaws[i].s; 13 } else if (DxfRaws[i].groupCode == 8) { 14 ent.LayerName = DxfRaws[i].s; 15 //Console.WriteLine("Layer Name = " + DxfRaws[i].s); 16 } else if (DxfRaws[i].groupCode == 10) { 17 ent.Line.Start.X = float.Parse(DxfRaws[i].s); 18 //Console.WriteLine(" X- " + DxfRaws[i].s); 19 } else if (DxfRaws[i].groupCode == 20) { 20 ent.Line.Start.Y = float.Parse(DxfRaws[i].s); 21 //Console.WriteLine(" Y- " + DxfRaws[i].s); 22 } else if (DxfRaws[i].groupCode == 11) { 23 ent.Line.End.X = float.Parse(DxfRaws[i].s); 24 //Console.WriteLine(" -X " + DxfRaws[i].s); 25 } else if (DxfRaws[i].groupCode == 21) { 26 ent.Line.End.Y = float.Parse(DxfRaws[i].s); 27 //Console.WriteLine(" -Y " + DxfRaws[i].s); 28 } 29 i++; 30 } 31 32//このあとで、dxfData.Entity.Add(ent);として、上で抽出したエンティティごとにリストに追加しています。 33//dxfdataというのは、パースの完了したDXFデータを保存するオブジェクトです。

以下これの繰り返し&線分以外の図形に対しても行っています

根本的に何がまずいのでしょうか
よろしくお願いいたします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

質問の内容と関係のないところがおかしくなっていたため発生していたようです
(無限ループ?)

お騒がせしました

投稿2017/04/15 01:48

ElecDove

総合スコア254

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問