Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Multi-thread API calls are impossible, but what about multiple processes?

frankloftus
Contributor

Multi-thread API calls are impossible, but what about multiple processes?

frankloftus
Contributor
Contributor

As stated in this post on TheBuildingCoder, Revit cannot make API calls from multiple threads within the same process:

 

https://thebuildingcoder.typepad.com/blog/2014/11/the-revit-api-is-never-ever-thread-safe.html 

 

At the end of the blog post, Jeremy mentions that using multiple processes is possible.

 

I just want to ask any experienced coders: Do you know of any reason why this can't be done? Are there any complications such as a need to use external events?

I am making API calls from IronPython and want to do some form of parallel processing. First I tried python's multiprocessing module, but IronPython doesn't have that. Then I tried parallel LINQ queries via .NET, but it turns out that uses multithreading, which is not allowed. Right now, I am using python's Subprocess module to spawn multiple processes that operate in parallel. This works within IronPython, but I have only done trivial tasks so far. I have not attempted to make multiple API calls from each process yet and I am wondering if this is possible.

 

I have searched the forum and have not seen a definitive answer to this, just rumors that it may be possible. Before I try it, it would be nice if someone already knows the answer. If I try it for myself, it will be hard for me to know if it is truly impossible, or if I have just made some tangential error, so please clue me in if you know the answer.

 

@jeremytammik, I will go ahead and mention you since you are the one who is likely to know. Thanks in advance!

0 Likes
Reply
Accepted solutions (1)
423 Views
6 Replies
Replies (6)

scgq425
Advocate
Advocate

Hi @frankloftus :

in my mind , the revit muti-thread is allowed when you want to get some data , but if you some action will change revit document , is will  not allowed.

LanHui Xu 徐兰辉
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Blog
LinkedIn
Revit/CAD Development | Steel Product Manager

EESignature

0 Likes

jeremy_tammik
Autodesk
Autodesk

Very simple: all Revit API calls must be made from and within a valid Revit API context, and that one and only context lives within the main thread. Everything else can be anywhere you like. So, do all the multi-processing and parallel computing you like, to your heart's content, but do not attempt to make any calls whatsoever to the Revit API from anywhere except the main thread and within the one and only valid Revit API context.

  

The valid Revit API context is provided by Revit within an event handler, such as the Execute method of an external command or an external event.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

frankloftus
Contributor
Contributor

I'm sure this feels like beating a dead horse, so I apologize for needing more clarification...

 

This is what I understand currently: A Revit addin acquires the API context through the Execute method of an external command when the addin is run. While one addin has the API context, no other addin may acquire a valid context until the first addin has completed and returned control to Revit. (Thus, the interface with the Revit API is single-threaded.)

 

If I am correct so far, it should be possible to spawn multiple subprocesses and have each subprocess make calls to the API as long as each call is actually made from the main process, which passes the data back to the subprocess that requested it. The issue then would be if two subprocesses ask the main process to make a call at the same time. I believe that Python subprocesses solve this by using a "pipe" to transfer data between the processes (the pipe acts like a queue that will serve the requests in order, I think).

 

So, as long as the main process keeps the API context and makes any API calls on behalf of its child processes, I believe multiprocessing should work for my use case.

 

I am not an expert, though. Does anyone disagree with what I have said above?

0 Likes

jeremy_tammik
Autodesk
Autodesk

> I'm sure this feels like beating a dead horse, so I apologize for needing more clarification...

Oh dear.

> A Revit addin acquires the API context through the Execute method of an external command when the addin is run.

... or some other Revit API event handler.

> While one addin has the API context, no other addin may acquire a valid context until the first addin has completed and returned control to Revit. (Thus, the interface with the Revit API is single-threaded.)

Yes.

> it should be possible to spawn multiple subprocesses and have each subprocess make calls to the API as long as each call is actually made from the main process, which passes the data back to the subprocess that requested it. The issue then would be if two subprocesses ask the main process to make a call at the same time. I believe that Python subprocesses solve this by using a "pipe" to transfer data between the processes (the pipe acts like a queue that will serve the requests in order, I think). So, as long as the main process keeps the API context and makes any API calls on behalf of its child processes, I believe multiprocessing should work for my use case.

No way. As long as the Execute method has not returned, Revit will wait. No other main thread activity is possible.

Looking at it from the Revit UI, and using an external command as an example, the valid Revit API context is created by the following steps: User launches command > Revit creates a valid Revit API context and calls the external command Execute method.

Now nothing at all will happen until that method returns.

For your scenario to work, the user would have to launch another external command, i.e., click another button. Can she do so? Nope Revit is blocked.

> Does anyone disagree with what I have said above?

Yes, absolutely.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

frankloftus
Contributor
Contributor

> For your scenario to work, the user would have to launch another external command, i.e., click another button. Can she do so? Nope Revit is blocked.

 

I'm not sure if there is a misunderstanding here, but in my scenario, I am launching only one external command. This (the main process) would then launch subprocesses that run in parallel, but they do not make their own API calls. They instead do calculations and request that the main process performs API calls on their behalf. The main process will stay running, keeping the API context until all subprocesses are complete. The Revit UI will be blocked for the duration of the main process, which is as planned. I believe the one complication is the need to ferry data between the processes. I am not planning to do any "background processing" where the user can still work while operations are ongoing.

0 Likes

jeremy_tammik
Autodesk
Autodesk
Accepted solution

Aha. Yes, that sounds fine. The Revit API calls must be called from the main thread. Other threads that do not make any use of the API are completely OK and can do anything (else) they want.

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes