Message 1 of 2
Parallel DWG Reads
Not applicable
07-24-2020
06:06 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi.
My application (a .DLL which I netload in) accesses several DWGs selected in a windows form app and collects some block attribute info about them. How can I do this in parallel?
I don't need to save the DWG at all during processing.
DWG.cs:
public class DWG
{
public string DWGLocation;
public string DWGName;
public string DWGRev;
public List<string> DWGLayouts;
public string PDFName;
public bool PDFExists;
public bool IsDWGLocked;
public bool IsPlotPDFLocked;
public bool IsHistoricalPDFLocked;
public bool IsReviewPDFLocked;
// Class constructor based on passed parameter
public DWG(string dwgToProcess)
{
DWGLocation = dwgToProcess;
DWGName = Path.GetFileName(DWGLocation);
PDFExists = File.Exists(FileOps.Path(DWGLocation) + GlobalVals.plotDir + PDFName);
IsDWGLocked = FileOps.IsFileLocked(DWGLocation);
IsPlotPDFLocked = FileOps.IsFileLocked(FileOps.Path(dwgToProcess) + GlobalVals.plotDir + PDFName);
IsHistoricalPDFLocked = FileOps.IsFileLocked(FileOps.Path(dwgToProcess) + GlobalVals.historicalDir + PDFName);
IsReviewPDFLocked = FileOps.IsFileLocked(FileOps.Path(dwgToProcess) + GlobalVals.reviewDir + PDFName);
// Get the rev num and layout names from the DWG
try
{
DWGRev = "?";
List<string> layouts = new List<string>();
using (Database db = new Database(false, true))
{
db.ReadDwgFile(dwgToProcess, FileShare.Read, false, null);
db.CloseInput(true);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Layouts
DBDictionary layoutDict = (DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
ObjectId layoutId = entry.Value;
Layout layout = tr.GetObject(layoutId, OpenMode.ForRead) as Layout;
layouts.Add(layout.LayoutName);
}
}
DWGLayouts = layouts;
// Attribute
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
if (bt.Has(GlobalVals.titleblock))
{
// Open the block definition
var btr = (BlockTableRecord)tr.GetObject(bt[GlobalVals.titleblock], OpenMode.ForRead);
// Get the inserted block references ObjectIds
var ids = btr.GetBlockReferenceIds(true, true);
if (ids.Count > 0)
{
// Open the first block reference
var br = (BlockReference)tr.GetObject(ids[0], OpenMode.ForRead);
// Iterate through the attribute collection
foreach (ObjectId id in br.AttributeCollection)
{
// Open the attribute reference
var attRef = (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
// If the attribute tag is what we are searching for
if (attRef.Tag.Equals(GlobalVals.revtag, StringComparison.CurrentCultureIgnoreCase))
{
DWGRev = attRef.TextString == "" || attRef.TextString == " " ? "R0" : attRef.TextString;
break;
}
}
}
}
tr.Commit();
}
}
// Remove any spaces in the front or end of the REV val with trim in case of bad input
DWGRev.Trim();
PDFName = PDFOps.GetPDFName(DWGLocation, DWGRev);
}
catch (System.Exception ex)
{
ErrorHandler.ErrorReport(ex, "GetRevNum", "notify");
}
}
}
I create multiple instances of DWG like so:
foreach (string dwg in dialog.FileNames)
{
// Check if the DWG already exists in list view to prevent duplicates in list view and list
if (this.DwgList.FindItemWithText(dwg) == null)
{
// Create an instance of a DWG
var dwgEntry = new DWG(dwg);
// Make sure DWG is not locked
if (!dwgEntry.IsDWGLocked)
{
// Make sure no PDFs are locked
if (!dwgEntry.IsPlotPDFLocked && !dwgEntry.IsHistoricalPDFLocked && !dwgEntry.IsReviewPDFLocked)
{
// Add the item to the List & list view
GlobalVals.dwgs.Add(dwgEntry);
AddListViewItem(dwgEntry);
}
else
{
// Some or all of the PDFs are locked
foreach (string error in FileOps.WhichPDFsAreLocked(dwgEntry))
{
errors.Add(error);
}
}
}
else if (dwgEntry.IsDWGLocked)
{
errors.Add("The drawing " + dwgEntry.DWGName + " is currently open by a user.");
}
}
else
{
errors.Add("The drawing " + Path.GetFileName(dwg) + " is already in the list.");
}
}
I tried doing it in parallel here, which crashed my AutoCAD:
Parallel.ForEach(dialog.FileNames, (dwg) = >
{
// Same body code as above
}
Later in my code, I create a consolidated DSD file from the information in DWG object and send it to the publisher.