This Visual Studio 2008 C# Solution demonstrates how to safely make calls crossing thread boundaries in a SolidWorks add-in written in C#.
The interfaces making up the SolidWorks API are implemented by COM co-classes, which are marked as "Single Thread Apartment" (STA).
This means that their methods can only be called on the thread on which the co-class was created. In this case that will be the main thread of the SolidWorks application sldworks.exe. This makes the SolidWorks API inhererently thread safe.
Threads are hosted in so-called COM "apartments". The COM run-time will assist in ensuring calls into the SolidWorks API made from another thread ( read apartment) than the main thread (read apartment) are correctly marshalled and executed on that main thread.
As a result this thread safety comes at a cost, as a call across thread boundaries implies a thread switch.
C# is not aware of COM apartments, hence there is a possibility an application method is called on another thread
than the main thread. Every call from there into the SolidWorks API will require the COM run-time to marshall the API call.
This may slow down an application considerably, as a thread switch is incurred for each call.
This could happen in two cases:
- SolidWorks loads documents in a background thread and fires events that C# API applications can listen to.
- an external application obtains a reference to an add-in loaded into SolidWorks and calls methods on
a COM interface exposed by that add-in.
The COM calls enter the sldworks.exe process on a background RPC thread, which will then directly
call C# code on that background thread.
To avoid a performance penalty one should first marshall a C# application call onto the main thread and only call SolidWorks API methods from there.
This solution illustrates how to detect when calls need to be marshalled and how to marshall them, comparing DocumentLoadNotify and its successor DocumentLoadNotify2.The latter was introduced to guarantee the event is delivered to an application on the main thread.
A separate application is provided, calling into a user defined interface IAddinExtender implemented by the add-in.
The interface allows for loading the small sample assembly that is provided.
In the code change the path to a assembly.
Alternatively load the assembly through the SolidWorks UI "File\Open".
To see the use of a background thread to load a SolidWorks model in action, uncheck the option:
“Tools\Options\System Options\Performance : No preview during open (faster)”
A helper class "ThreadMarshaller" is introduced which derives from System.Windows.Forms.Control.
This base class provides a mechanism for call marshalling using delegates.
As a bonus the same approach is used to marshal .NET timer events being fired from a .NET thread pool
to the main SolidWorks thread to display a message in the SolidWorks statusbar.
Minimum SolidWorks version:
- for 32-bit SolidWorks 2010
- for 64-bit SolidWorks 2010
|- required for full access.|
- Looking for more API Examples?
This item is also published as Solution S-054520 in the SolidWorks Knowledge Base.
Copyright © 2011 Dassault Systèmes SolidWorks Corp. All rights reserved.
Do not distribute or reproduce without the written consent of Dassault Systèmes SolidWorks Corp.