What's new

Wait until part generation is completed

Hello everyone,

1729417302159.png

Is there any possibility to wait until the part generation is finished?

Currently i want to do some part generation and i have to work with thread sleep to secure, that the part generation is finished.
AddExtrudedBoss returns and sometimes the part generation in Alibre is still running.

If i want to access the Edges from the part i will get this exception:

"System.Runtime.InteropServices.COMException (0x8004024C): Can't execute query. Object no longer exists in server"

But this is only because the part is still generating.

When i introduce long sleeps it will work, but i think this couldn't be the solution.

I would like to thank you in advance for your support.

Greetings and have a nice day

Hint:
part is IADPartSession
 

stepalibre

Alibre Super User
You should check the session state for access prior to calling methods on that generated part or any Alibre code. I avoid Thread.Sleep in situations like this. That function should run without any thread.sleeping as it is not predictable. The amount you sleep can be too long, too short or have no effect.

I utilize a separate process for this use case, COM can be messy and Alibre is unpredictable. A separate process called by Process.Start can wait until the work has completed and then you'll receive it ready to use. You should check if it is working or not before you proceed.

Or

Use an async Task with Process.Start

Or

Run your code above in headless/GUI-less mode, with an async Task. You don't need to use async task, you can use Process.Start().Wait().

Ultimately I recommend separating your part generation code from your main calling or main process program/code.

Thread sleeping can be pointless when using COM as objects and collections aren't updated while you sleep. You'll need to reinitialize all those variables to get the updates. I program COM APIs as if they are separate machines or servers. I'm talking about in a full application not a single function as you shared.
 
Last edited:

stepalibre

Alibre Super User
Take a look at this code:



I rarely get COMException errors when creating geometry, maybe you can try a different approach. Without seeing all your code I can't answer this question:

Is there any possibility to wait until the part generation is finished?
 

stepalibre

Alibre Super User
You should check the session state for access prior to calling methods on that generated part or any Alibre code. I avoid Thread.Sleep in situations like this. That function should run without any thread.sleeping as it is not predictable. The amount you sleep can be too long, too short or have no effect.

I utilize a separate process for this use case, COM can be messy and Alibre is unpredictable. A separate process called by Process.Start can wait until the work has completed and then you'll receive it ready to use. You should check if it is working or not before you proceed.

Or

Use an async Task with Process.Start

Or

Run your code above in headless/GUI-less mode, with an async Task. You don't need to use async task, you can use Process.Start().Wait().

Ultimately I recommend separating your part generation code from your main calling or main process program/code.

Thread sleeping can be pointless when using COM as objects and collections aren't updated while you sleep. You'll need to reinitialize all those variables to get the updates. I program COM APIs as if they are separate machines or servers. I'm talking about in a full application not a single function as you shared.
Take a look at this code:



I rarely get COMException errors when creating geometry, maybe you can try a different approach. Without seeing all your code I can't answer this question:

One last comment:

Sleeping threads are perfectly fine, in certain instances. When creating geometry, thread.sleeping can cause problems because the amount of time needed can vary or be unpredictable. I use thread sleeping to account for GUI operations that take some varying or fixed amount of time. For example switching configurations or regenerating has some overhead in GUI mode. You may need to wait in your code until Alibre is finished. And the more complex or large the Alibre file is the longer that process will take.
 
One last comment:

Sleeping threads are perfectly fine, in certain instances. When creating geometry, thread.sleeping can cause problems because the amount of time needed can vary or be unpredictable. I use thread sleeping to account for GUI operations that take some varying or fixed amount of time. For example switching configurations or regenerating has some overhead in GUI mode. You may need to wait in your code until Alibre is finished. And the more complex or large the Alibre file is the longer that process will take.
Yes i know, and this leads to my question.

So i saw in your code a lot of "the" same problems, but currently you wouldn't recognize it because there are no additional operations on it.

For example:

1730644922924.png

Line 47, what if you want to have an access on solid2.body.edges?

you can't do it directly after line 47 because if the geometry is a bit complex an additional generation window on alibre side will appear or a processbar in the part window appears in the lower right corner (statusbar)

Another question here:
Are those sleeps intended for animaton:
1730646292439.png
If not this is the same thing.


So back to my example:

1730645785137.png

Here:

Thread sleep is required, when i work without it i cannot access part.Bodies.Count or part.Bodies.Item ... because of: i think race conditions between unsynchonized threads.

Is there any possiblilitie to connect the part session to an event from alibre where i can get any information that IADExtrusionFeature is finished and the part is generated at that point?

Or is there another possibility to get some information about that? Something like an *await* or callbacks or a flag in the Geometry Factory which says part generation ready for next step.

(I work with Alibre V26 from March 2023)
 

stepalibre

Alibre Super User
Line 47, what if you want to have an access on solid2.body.edges?
you can't do it directly after line 47 because if the geometry is a bit complex an additional generation window on alibre side will appear or a processbar in the part window appears in the lower right corner (statusbar)
I would create another function to work with topology, store it in a list, object or write it to file.
Are those sleeps intended for animaton:

That is to debug the automation, not intended to be production code although it works. The delay is to allow me to check each step. I watch the GUI while stepping through calls. I have each "create" feature inside its own function.

Instead of thread sleep, I use tasks or some other technique to wait until work is finished before proceeding.

Thread sleeping inside a method before or after a call is made is a better approach to your code example since the functions needs to complete before the next function is called. With a delay between calls this helps to ensure Alibre is ready or it will allow you to perform tests or checks. It also helps me debug Alibre code, working in units or steps, multiple functions, instead of one function.

When it crash, you can look at the call stack and other dev tools to understand what broke and when. The COM or Alibre caught exceptions aren't as useful so having code in separate calls can help.

Thread sleep is required, when i work without it i cannot access part.Bodies.Count or part.Bodies.Item ... because of: i think race conditions between unsynchonized threads.

Is there any possiblilitie to connect the part session to an event from alibre where i can get any information that IADExtrusionFeature is finished and the part is generated at that point?

Or is there another possibility to get some information about that? Something like an *await* or callbacks or a flag in the Geometry Factory which says part generation ready for next step.

I think generally:
Feature methods add, create, update or delete topology or data in general. Topology methods query or read data, possibly fully committed or saved to the file.

Combining Create and Query work in the same function is not how I build things and would suggest splitting into two functions. Topology code should be a separate call made only after you confirm in your code that the ExtrusionFeatures is ready. You can use headless mode or run a separate process to get topology information if you continue to have problems. If you're creating a lot of features or have complex modeling, you might need another solution if AlibreX is not working.

AlibreX doesn't have any safeguards in place to prevent these conditions. We have to build our own on top of AlibreX.

I never experience these issues (can't recall ever) when developing with Excel, SolidWorks, Inventor or SolidEdge COM API's. These issues are unique to Alibre Design COM.
 
Last edited:

stepalibre

Alibre Super User
I forgot what I wrote and had to read thread again.

Few questions:
Is this a addon, console, winforms, or WPF program?
What are you generating/creating?

Remove your topology code and run or integrate this code to learn if it works with your model:

C#:
public class Program
{
    public static IADSession Session;
    public static IADPartSession objADPartSession;
    public static IAutomationHook Hook;
    public static IADRoot Root;
    public static void Main()
    {
        Hook = (IAutomationHook)Marshal.GetActiveObject("AlibreX.AutomationHook");
        Root = (IADRoot)Hook.Root;
        Session = Root.Sessions.Item(0);
        objADPartSession = (IADPartSession)Session;
        Console.WriteLine(Session.FilePath);
        Console.WriteLine(objADPartSession.Bodies.Count);
        IADBodies b = objADPartSession.Bodies;
        IADVertices verts = b.Item(0).Vertices;
        Console.WriteLine(verts.Count);
        for (int i = 0; i <= verts.Count - 1; i++)
        {
            printpoint(verts.Item(i).Point.X, verts.Item(i).Point.Y, verts.Item(i).Point.Z);
        }
        IADFaces c = b.Item(0).Faces;
        for (int j = 0; j <= c.Count - 1; j++)
        {
            Console.WriteLine(c.Item(j).Edges.Count);
        }
        Hook = null;
        Root = null;
    }
    public static void printpoint(dynamic x, dynamic y, dynamic z)
    {
        Console.WriteLine(x + " , " + y + " , " + z);
    }
}
 
Top