We talked about the 128 count limit of available selection sets existing in both Auto/Visual LISP and AutoCAD .NET API previously, and demonstrated about it with code examples and running results. What about it in the AutoCAD ActiveX/COM API then?
Let us figure it out with some simple but functional code.
[CommandMethod("TestComSelectionSetCountLimit", CommandFlags.Modal)]
public void TestComSelectionSetCountLimit()
{
AcadApplication comApp = MgdAcApplication.AcadApplication as AcadApplication;
AcadDocument comDoc = comApp.ActiveDocument;
AcadSelectionSets comSSes = comDoc.SelectionSets;
try
{
for (int i = 0; i < 130; i++)
{
AcadSelectionSet comSs = comSSes.Add(string.Format("SS{0}", i + 1));
if (comSs != null)
{
comSs.Select(Autodesk.AutoCAD.Interop.Common.AcSelect.acSelectionSetAll);
comDoc.Utility.Prompt(string.Format("\nThe #{0} SS is good and has {1} entities.", i + 1, comSs.Count));
}
else
comDoc.Utility.Prompt(string.Format("\nThe #{0} SS is bad!", i + 1));
}
}
catch (System.Exception ex)
{
comDoc.Utility.Prompt(Environment.NewLine+ ex.ToString());
}
}
If an AutoCAD session is launched, a new drawing is created, a circle is added to the database, and the command is run, we will see some results as follows.
AutoCAD menu utilities loaded.
Command:
Command:
Command: c CIRCLE Specify center point for circle or [3P/2P/Ttr (tan tan
radius)]:
Specify radius of circle or [Diameter]:
Command: TestComSelectionSetCountLimit
Command:
The #1 SS is good and has 1 entities.
Command:
The #2 SS is good and has 1 entities.
Command:
The #3 SS is good and has 1 entities.
…
Command:
The #126 SS is good and has 1 entities.
Command:
The #127 SS is good and has 1 entities.
Command:
System.Runtime.InteropServices.COMException (0x80020009): Exception occurred.
(Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION))
at Autodesk.AutoCAD.Interop.IAcadSelectionSet.Select(AcSelect Mode, Object
Point1, Object Point2, Object FilterType, Object FilterData)
…
As can be seen, in the AutoCAD ActiveX/COM API, the limitation is also there, and the amount of all active selection sets is one less than the limit in the LISP and .NET API, 128, which is interesting. There must be something there to cause the tiny inconsistency, likely a default selection set is somewhere in the ActiveX/COM selection set collection. We don’t bother to nail it down here since it’s not the major concern. Though the sample code is in AutoCAD .NET C# COM Interop, it will apply to other ActiveX/COM flavors too without any doubt such as VB, VBA, and VB.NET COM Interop.
By the way, at this moment, no valid selection sets can be created anymore by anybody including but not limited to ActiveX/COM, .NET API and LISP anywhere either in the current document or in a newly opened one. Worse than the LISP situation that was demonstrated before, it won’t help either even to close the active document/drawing in which the above test is performed. Closing and reopening AutoCAD apparently helps but it will disturb the work process much more.
What is the good practice to address the issue then?
It is good to explicitly free the ActiveX/COM selection sets of concern when we are done to them as demonstrated below.
[CommandMethod("TestComSelectionSetCountLimit2", CommandFlags.Modal)]
public void TestComSelectionSetCountLimit2()
{
AcadApplication comApp = MgdAcApplication.AcadApplication as AcadApplication;
AcadDocument comDoc = comApp.ActiveDocument;
AcadSelectionSets comSSes = comDoc.SelectionSets;
try
{
for (int i = 0; i < 130; i++)
{
AcadSelectionSet comSs = comSSes.Add(string.Format("SS{0}", i + 1));
if (comSs != null)
{
comSs.Select(Autodesk.AutoCAD.Interop.Common.AcSelect.acSelectionSetAll);
comDoc.Utility.Prompt(string.Format("\nThe #{0} SS is good and has {1} entities.", i + 1, comSs.Count));
//Do anything to the selection set such as iterations.
//...
comSs.Delete();
Marshal.FinalReleaseComObject(comSs);
}
else
comDoc.Utility.Prompt(string.Format("\nThe #{0} SS is bad!", i + 1));
}
}
catch (System.Exception ex)
{
comDoc.Utility.Prompt(Environment.NewLine + ex.ToString());
}
finally
{
if (comSSes != null)
{
for (int i = 0; i < comSSes.Count; i++ )
{
comSSes.Item(i).Delete();
Marshal.FinalReleaseComObject(comSSes.Item(i));
}
Marshal.FinalReleaseComObject(comSSes);
}
if (comDoc != null) Marshal.FinalReleaseComObject(comDoc);
if (comApp != null) Marshal.FinalReleaseComObject(comApp);
}
}
Once again, if we launch an AutoCAD session, create a new drawing, add a circle to it for example, and run the command, we will get the following output this time.
Command:
AutoCAD menu utilities loaded.*Cancel*
Command:
Command: NetLoad Assembly file name:
C:/API/Acad.NET/AcadNetTest_VS2010/AcadNetTest/bin/Debug/AcadNetTest.dll
Command: Test Test Command.
Command:
Command: c CIRCLE Specify center point for circle or [3P/2P/Ttr (tan tan
radius)]:
Specify radius of circle or [Diameter]:
Command: TestComSelectionSetCountLimit2
Command:
The #1 SS is good and has 1 entities.
Command:
The #2 SS is good and has 1 entities.
Command:
The #3 SS is good and has 1 entities.
...
The #127 SS is good and has 1 entities.
Command:
The #128 SS is good and has 1 entities.
Command:
The #129 SS is good and has 1 entities.
Command:
The #130 SS is good and has 1 entities.
Command:
As can be seen, the #128, #129 and #130 selection sets are successfully created. If we like we can create as many as possible selection sets and operate on them this way.
To recap, the 128 or 127 count limit of selection sets is also there in the AutoCAD ActiveX/COM API, and the good practice is to release the ActiveX/COM selection sets of concern as soon as possible.
By the way, the code example also shows a nice way to handle exceptions in the .NET COM Interop code. Whenever any exception occurs, the ActiveX/COM objects and resources will be explicitly released, including releasing any selection sets back to the static pool, which is shared by everybody inside AutoCAD, e.g. its APIs, Commands, Users, Scripts, etc.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides a coder, Entity Jigger, to help us create entity jig code automatically, quickly and reliably.
Posted by: |