<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Parallel DWG Reads in .NET Forum</title>
    <link>https://forums.autodesk.com/t5/net-forum/parallel-dwg-reads/m-p/9653531#M18912</link>
    <description>&lt;P&gt;Hi.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't need to save the DWG at all during processing.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;DWG.cs:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;public class DWG
{

	public string DWGLocation;
	public string DWGName;
	public string DWGRev;
	public List&amp;lt;string&amp;gt; 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&amp;lt;string&amp;gt; layouts = new List&amp;lt;string&amp;gt;();

			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 &amp;gt; 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");
		}
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I create multiple instances of DWG like so:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;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 &amp;amp;&amp;amp; !dwgEntry.IsHistoricalPDFLocked &amp;amp;&amp;amp; !dwgEntry.IsReviewPDFLocked)
			{
				// Add the item to the List &amp;amp; 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.");
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried doing it in parallel here, which crashed my AutoCAD:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;Parallel.ForEach(dialog.FileNames,  (dwg) = &amp;gt;
{
	// Same body code as above
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Later in my code, I create a consolidated DSD file from the information in DWG object and send it to the publisher.&lt;/P&gt;</description>
    <pubDate>Fri, 24 Jul 2020 13:24:06 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2020-07-24T13:24:06Z</dc:date>
    <item>
      <title>Parallel DWG Reads</title>
      <link>https://forums.autodesk.com/t5/net-forum/parallel-dwg-reads/m-p/9653531#M18912</link>
      <description>&lt;P&gt;Hi.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I don't need to save the DWG at all during processing.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;DWG.cs:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;public class DWG
{

	public string DWGLocation;
	public string DWGName;
	public string DWGRev;
	public List&amp;lt;string&amp;gt; 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&amp;lt;string&amp;gt; layouts = new List&amp;lt;string&amp;gt;();

			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 &amp;gt; 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");
		}
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I create multiple instances of DWG like so:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;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 &amp;amp;&amp;amp; !dwgEntry.IsHistoricalPDFLocked &amp;amp;&amp;amp; !dwgEntry.IsReviewPDFLocked)
			{
				// Add the item to the List &amp;amp; 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.");
	}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried doing it in parallel here, which crashed my AutoCAD:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;Parallel.ForEach(dialog.FileNames,  (dwg) = &amp;gt;
{
	// Same body code as above
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Later in my code, I create a consolidated DSD file from the information in DWG object and send it to the publisher.&lt;/P&gt;</description>
      <pubDate>Fri, 24 Jul 2020 13:24:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/parallel-dwg-reads/m-p/9653531#M18912</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2020-07-24T13:24:06Z</dc:date>
    </item>
    <item>
      <title>Re: Parallel DWG Reads</title>
      <link>https://forums.autodesk.com/t5/net-forum/parallel-dwg-reads/m-p/9657337#M18913</link>
      <description>&lt;P&gt;just a quick result for a quick research on this forum:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://forums.autodesk.com/t5/net/parallel-read-from-net/m-p/6397148" target="_blank" rel="noopener"&gt;https://forums.autodesk.com/t5/net/parallel-read-from-net/m-p/6397148&lt;/A&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;some quoted text: &lt;EM&gt;"...There is no parallel processing in AutoCAD.&amp;nbsp; For better performance I would first suggest...&amp;nbsp;"&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://forums.autodesk.com/t5/net/parallel-loop/m-p/3726470" target="_blank" rel="noopener"&gt;https://forums.autodesk.com/t5/net/parallel-loop/m-p/3726470&lt;/A&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;again some quoted text: &lt;EM&gt;"...Sorry for the bad news, but the AutoCAD API isn't thread safe. You can....&amp;nbsp;"&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 27 Jul 2020 13:15:23 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/parallel-dwg-reads/m-p/9657337#M18913</guid>
      <dc:creator>micle.space</dc:creator>
      <dc:date>2020-07-27T13:15:23Z</dc:date>
    </item>
  </channel>
</rss>

