[CONNECT C#] Faster method to extract all element Item Type Property values?

Hi all,

I am trying to cycle through the elements in a dgn model and extract all Item Type property values for them but am finding that the EC IDgnInstance GetPropertyValue method is quite slow (takes 7 seconds per element that has approx 20 values). I need to do this for 1000s of elements so this method will take hours to run.

Does anyone have any ideas to get Item Type property values extracted to a List faster? I am using the latest version of Microstation (U17.1).

Note that it looks to bog down for string values that were generated from Expressions.

using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.ECObjects;
using Bentley.ECObjects.Instance;


CustomItemHost customItemHost = new CustomItemHost(element, false);
IEnumerator<IDgnECInstance> customItemList = customItemHost.CustomItems.GetEnumerator();

while (customItemList.MoveNext())
{
    IDgnECInstance customItem = customItemList.Current;
    ItemType itemType = null;

    foreach (ItemTypeLibrary itemTypeLibrary in ItemTypeLibraries)
    {
        if (itemTypeLibrary.HasInstancesInFile && itemTypeLibrary.ItemTypeCount > 0)
        {
            itemType = itemTypeLibrary.GetItemTypeByName(customItem.ClassDefinition.Name);

            if (itemType = null)
            {
                break;
            }

            CustomPropertyContainer itemTypeCont = itemType;

            foreach (CustomProperty customProperty1 in itemTypeCont)
            {
                if (customProperty1 != null)
                {
                    string propName = customProperty1.InternalName;
                    object propValOut = null;
                    IECPropertyValue propVal = null;
                    propVal = customItem.GetPropertyValue(propName);
                    int type = (int)customProperty1.Type;
                    
                    
                    if (type == 0)
                    {
                        propValOut = Convert.ToBoolean(propVal.IntValue);
                    }
                    else if (type == 2)
                    {
                        propValOut = propVal.DoubleValue;
                    }
                    else if (type == 3)
                    {
                        propValOut = propVal.IntValue;
                    }
                    else if (type == 4)
                    {
                        DPoint3d dpoint3d = DPoint3d.FromXY(0.0, 0.0);
                        dpoint3d = (DPoint3d)propVal.NativeValue;
                        propValOut = (string)(dpoint3d.X + "," + dpoint3d.Y);
                    }
                    else if (type == 5)
                    {
                        propValOut = propVal.StringValue;
                    }
                    else
                    {
                        propValOut = propVal.NativeValue;
                    }
                }
            }
        }
    }

Regards,

Mark

Parents
  • Hi Mark,

    Your code snippet will be slower. You are iterating each element, then for each element, you are doing itemTypeLibrary.HasInstancesInFile. This method will query the whole dgn to check if all library classes have instances. I think you don't need the following loop:

    foreach (ItemTypeLibrary itemTypeLibrary in ItemTypeLibraries)
    {
    if (itemTypeLibrary.HasInstancesInFile && itemTypeLibrary.ItemTypeCount > 0)
    {

    And, with Direct EC APIs you can avoid iterating all elements:

    1. Create ECQuery for all classes.  ECQuery readGadget = new ECQuery(<list of all classes>);readGadget.SelectClause.SelectAllProperties = true;

    2. Create scope: 

    FindInstancesScope scope = FindInstancesScope.CreateScope(activeDgnModel.GetDgnFile(), new FindInstancesScopeOption(DgnECHostType.Element));

    3. Execute:

    DgnECInstanceCollection instanceCollection = dgnECManager.FindInstances(scope, readGadget);

    Please try SDK sample: MstnExamples\DgnEC\DgnECCrudExample\ManagedExample.

    Thanks,

    Mangesh


    This is a test

Reply
  • Hi Mark,

    Your code snippet will be slower. You are iterating each element, then for each element, you are doing itemTypeLibrary.HasInstancesInFile. This method will query the whole dgn to check if all library classes have instances. I think you don't need the following loop:

    foreach (ItemTypeLibrary itemTypeLibrary in ItemTypeLibraries)
    {
    if (itemTypeLibrary.HasInstancesInFile && itemTypeLibrary.ItemTypeCount > 0)
    {

    And, with Direct EC APIs you can avoid iterating all elements:

    1. Create ECQuery for all classes.  ECQuery readGadget = new ECQuery(<list of all classes>);readGadget.SelectClause.SelectAllProperties = true;

    2. Create scope: 

    FindInstancesScope scope = FindInstancesScope.CreateScope(activeDgnModel.GetDgnFile(), new FindInstancesScopeOption(DgnECHostType.Element));

    3. Execute:

    DgnECInstanceCollection instanceCollection = dgnECManager.FindInstances(scope, readGadget);

    Please try SDK sample: MstnExamples\DgnEC\DgnECCrudExample\ManagedExample.

    Thanks,

    Mangesh


    This is a test

Children
No Data