Transaction Commit Delays and Missing Display for Appended Entities in Large Drawings

Transaction Commit Delays and Missing Display for Appended Entities in Large Drawings

rampseeker
Advocate Advocate
244 Views
1 Reply
Message 1 of 2

Transaction Commit Delays and Missing Display for Appended Entities in Large Drawings

rampseeker
Advocate
Advocate

크기가 약 150MB인 도면 파일로 작업하고 있으며, 모델 공간에 있는 엔터티의 유형과 수량은 다음과 같습니다.

 

▶ number of Entity : 79,611  ◀
  - Line: 19,755
  - Polyline: 18,778
  - Polyline2d: 7,356
  - DBText: 4,097
  - Section: 3,049
  - DBPoint: 3,026
  - FeatureLine: 2,768
  - MaterialSection: 2,637
  - Circle: 2,230
  - Arc: 2,027
  - Alignment: 1,815
  - AutoCorridorFeatureLine: 1,347
  - Profile: 1,206
  - AlignmentStationLabelGroup: 695
  - AlignmentMinorStationLabelGroup: 695
  - AlignmentVerticalGeometryPointLabelGroup: 654
  - AlignmentGeometryPointLabelGroup: 652
  - AlignmentStationEquationLabelGroup: 652
  - AlignmentDesignSpeedLabelGroup: 652
  - AlignmentSuperelevationLabelGroup: 652
  - Solid3d: 603
  - SectionViewQuantityTakeoffTable: 514
  - SampleLine: 501
  - SectionView: 501
  - CorridorSection: 488
  - TinSurface: 364
  - Grading: 309
  - Subassembly: 274
  - Polyline3d: 237
  - Body: 217
  - Assembly: 148
  - Site: 95
  - SectionDataBandLabelGroup: 89
  - CogoPoint: 81
  - Corridor: 69
  - SampleLineGroup: 44
  - SampleLineLabelGroup: 44
  - ProfileView: 39
  - ProfileDataBandLabelGroup: 39
  - ProfileLineLabelGroup: 39
  - ProfilePVILabelGroup: 39
  - ProfileSagCurveLabelGroup: 39
  - ProfileCrestCurveLabelGroup: 39
  - Sheet: 31
  - Hatch: 11
  - BlockReference: 9
  - TinVolumeSurface: 3
  - MText: 1
  - AutoFeatureLine: 1

 

 

 

문제는 빈 도면에서 btr.AppendEntity(resultPoly);를 실행한 다음 trans.Commit();을 수행하면 폴리라인이 화면에 정상적으로 표시된다는 것입니다.

하지만 규모가 큰 도면에서는 거래를 완료한 후에도 폴리라인이 화면에 표시되지 않습니다.

trans.AddNewlyCreatedDBObject(br, true);를 실행하면 도면에 제대로 표시되지만, 문제는 도면에 이미 많은 수의 엔터티가 있기 때문에 trans.AddNewlyCreatedDBObject(br, true);를 사용하여 모든 객체를 추가한 다음 trans.Commit();을 수행하면 최소 10분을 기다려야 한다는 것입니다.

이런 일이 발생하는 이유와 trans.AddNewlyCreatedDBObject(br, true)를 사용하지 않고도 폴리라인을 표시할 수 있는 방법이 있는지 알고 싶습니다.

 

아래는 다른 접근방법을 사용하여 실행 시간을 줄이려고 테스트한 코드입니다.

 

1. W블록 

public void TestWblock10()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    Stopwatch sw = Stopwatch.StartNew();

    using (Database tempDb = new Database(true, true))
    {
        using (Transaction tr = tempDb.TransactionManager.StartTransaction())
        {
            BlockTable bt = tr.GetObject(tempDb.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            int totalPolylines = 100000;
            double spacing = 10.0;
            for (int i = 0; i < totalPolylines; i++)
            {
                Polyline p = new Polyline();
                p.SetDatabaseDefaults(tempDb);

                double offsetX = (i % 1000) * spacing;
                double offsetY = (i / 1000) * spacing;

                p.AddVertexAt(0, new Point2d(offsetX, offsetY), 0, 0, 0);
                p.AddVertexAt(1, new Point2d(offsetX + 5, offsetY), 0, 0, 0);
                p.AddVertexAt(2, new Point2d(offsetX + 5, offsetY + 5), 0, 0, 0);
                p.AddVertexAt(3, new Point2d(offsetX, offsetY + 5), 0, 0, 0);
                p.Closed = true;
                p.ColorIndex = (i % 7) + 1; 

                btr.AppendEntity(p);
                tr.AddNewlyCreatedDBObject(p, true);  

                if ((i + 1) % 20000 == 0)
            }

            tr.Commit(); 
        }


        ObjectId blockDefId = db.Insert("poly_block", tempDb, true);

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord ms = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            BlockReference br = new BlockReference(Point3d.Origin, blockDefId);
            ms.AppendEntity(br);
            tr.AddNewlyCreatedDBObject(br, true);

            tr.Commit();
        }
    }

    sw.Stop();
    ed.Regen();
    
}

 

2. ID 매핑

```csharp
[CommandMethod("Test_DeepClone")]
public void TestDeepClone()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    Stopwatch sw = Stopwatch.StartNew();

    using (Database tempDb = new Database(true, true))
    {
        using (Transaction tr = tempDb.TransactionManager.StartTransaction())
        {
            BlockTable bt = tr.GetObject(tempDb.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            int total = 100000;
            double spacing = 10.0;

            for (int i = 0; i < total; i++)
            {
                Polyline p = new Polyline();
                p.SetDatabaseDefaults(tempDb);
                double offsetX = (i % 1000) * spacing;
                double offsetY = (i / 1000) * spacing;

                p.AddVertexAt(0, new Point2d(offsetX, offsetY), 0, 0, 0);
                p.AddVertexAt(1, new Point2d(offsetX + 5, offsetY), 0, 0, 0);
                p.AddVertexAt(2, new Point2d(offsetX + 5, offsetY + 5), 0, 0, 0);
                p.AddVertexAt(3, new Point2d(offsetX, offsetY + 5), 0, 0, 0);
                p.Closed = true;

                btr.AppendEntity(p);
                tr.AddNewlyCreatedDBObject(p, true);
            }

            tr.Commit();
        }
        using (Transaction trDest = db.TransactionManager.StartTransaction())
        {
            BlockTable destBT = trDest.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord destMS = trDest.GetObject(destBT[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            ObjectIdCollection objIds = new ObjectIdCollection();
            using (Transaction trsrc=tempDb.TransactionManager.StartTransaction())
            {
                BlockTable srcBT = trSrc.GetObject(tempDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord srcMS = trSrc.GetObject(srcBT[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

                foreach (ObjectId entId in srcMS)
                {
                    objIds.Add(entId);
                }
                trSrc.Commit();
            }

            IdMapping mapping = new IdMapping();

            db.WblockCloneObjects(
                objIds,            
                destMS.ObjectId,   
                mapping,           
                DuplicateRecordCloning.Ignore, 
                false              
            );

            trDest.Commit();
        }
    }

    sw.Stop();
    ed.Regen();
    
}

```

 

btr.AppendEntity(resultPoly);를 실행한 후 resultPoly.Draw()를 호출하면 폴리라인이 화면에 시각적으로 표시됩니다.
그러나 Audit을 수행한 다음 Regen을 수행할 때까지 개체로 선택할 수 없습니다.
문제는 이 그림이 매우 크고 Audit을 실행하는 데 한 시간 이상 걸린다는 것입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 Likes
Accepted solutions (1)
245 Views
1 Reply
Reply (1)
Message 2 of 2

ActivistInvestor
Mentor
Mentor
Accepted solution

In an external database, Transactions are not really needed because they can't be rolled back. 

 

Don't use Transactions. Instead just call DBObject.Close(), as is shown in this thread:

0 Likes