Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can the method "SetExecutionOrder" by used to set the order of more than two IUpdaters

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
TheRealChrisHildebran
389 Views, 12 Replies

Can the method "SetExecutionOrder" by used to set the order of more than two IUpdaters

Revit API Reference: https://www.revitapidocs.com/2021.1/87d62116-cdb4-efc4-e2e2-e4f5b41b3441.htm 

 

We have about eight IUpdaters in our addin and have the need to specify the order in which they fire. 

 

Has anyone had this need and if so, do you know if you can set the order of more than two?

 

I was thinking a "Two at a time" approach setting the order of one pair (as allowed using the SetExecutionOrder) IUpdaters then continuing this for the remaining in a list each time incrementing an index. 

 

Below is a concrete example rather than a loop which would be used instead. Just thought it would be easier to visualize.  

 

public static void SetExecutionOrder (Updater7.Id,Updater8.ID);
public static void SetExecutionOrder (Updater6.Id,Updater7.ID);
public static void SetExecutionOrder (Updater5.Id,Updater6.ID);
public static void SetExecutionOrder (Updater4.Id,Updater5.ID);
public static void SetExecutionOrder (Updater3.Id,Updater4.ID);
public static void SetExecutionOrder (Updater2.Id,Updater3.ID);
public static void SetExecutionOrder (Updater1.Id,Updater2.ID);

  

12 REPLIES 12
Message 2 of 13

Since every updater adds a performance hit to the model processing and execution time, and since you need to control the order in a way that may go beyond what the Revit API offers built-in, I wonder whether it might not be both more efficient, simpler to handle, and safer, if you took things into your own hands and implemented one single top-level updater that handles the processing of the eight ones you are currently working with from one single centralised Execute call? Sure, it will add complexity in some places, but it might significantly reduce it in others. Just a question to ponder...

   

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 3 of 13

I wholeheartedly agree with your suggestion Jeremy. Fortunately, the IUpdater system we have set up is working fine (aside from the execution order need) even on large modes (+1GB) but...the system does have a code smell. We do address a bit of technical debt in each sprint: When can we do it is the question. We have quite a backlog of cool things to implement. 

 

Perhaps i should have prefaced my OP by mentioning that we have consolidated our IUpdaters to the quantity we have currently, and that further consolidation is forthcoming. Until then we'd like to control the execution order. 

 

 

 

 

Message 4 of 13

It appears you can use the "SetExecutionOrder" iteratively. 

 

The list you pass in has to be ordered in the desired order. 

 

So, until i can consolidate a bit more this will work.

 

 

 

public void SetExecutionOrder(List<IUpdater> updaters)
{
var count = updaters.Count;

for (var i = 0; i < count; i++)
{
var previous = updaters[i].GetUpdaterId();

var last = updaters[i + 1].GetUpdaterId();

UpdaterRegistry.SetExecutionOrder(previous, last);
}
}

 

Message 5 of 13

Thank you for the interesting observation and confirmation!

 

Isn't your loop going one too far? 

 

I like doing suchlike things thus:

 

previous = null
foreach u in updaters
  if previous: process previous + u
  previous = u

 

 

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 6 of 13

Your experience and knowledge definitely beat my 5 years.

I'll definitely defer to a better way and always open to learn something new.

 

Message 7 of 13

Out of interest could you give a brief description of why you have implemented eight updaters in the single add-in?

 

We never know 100% for sure that an updater will not find itself disabled by Revit due to an unforeseen issue. I think therefore we can't really assume that one will execute before another we can only tell that if it does execute it will be before the other.

 

Therefore for me the execution order should be largely irrelevant in the design of the DMU since you can't overly rely on it. Also the update is all predefined the moment the update is triggered ideally you would do the most you could in the single execute method. Perhaps the only advantage of setting the order is to limit the retriggering, is that your aim?

Message 8 of 13

I want to reiterate that the number of IUpdaters hasn't had a noticeable negative effect on our model performance. Many of which approach 1GB in size. On the contrary, I'm confident our detailing department would revolt if taken away. 😊 Their inclusion offers so much productivity its worth whatever the performance hit is.

Soon after my post-dynamo start down the road of c# programming in 2017, I learned about these updaters and implemented several simple ones based on examples from the Autodesk website and The Building Coder website.

The several became a half dozen but were monstrous implementations with far too much "cyclomatic complexity". Most likely because of my inexperience in OOP, Revit API, and short-sightedness.

Around 2020 I split them up into, I'm guessing, about two dozen updaters. And subsequently pared down a bit more.

Today, they are lightweight and unobtrusive little micro-services with distinct work scopes. I could likely combine/refactor, and probably that review will happen later this year.

As far as updaters becoming disabled or their firing order, I'm not 100% convinced that they will continue to fire in the order I desire for the duration of the Application Session. Still, for all the testing so far, the updaters are firing in the order I asked them to.

I'm hopeful that soon I will be able to refactor the remaining DMU's into a better design.
Message 9 of 13

That's fine was just curious about your motivation for the order and the numbers of updaters. I never used that method probably wasn't available historically. I assume it is only included so you can better prevent one updater triggering another.

 

I always recall a situation from years ago when an end user colleague pinned down an odd delay in Revit to the precast add-in (as it was then a separate thing from main Revit). Whenever you moved something concrete or otherwise there was this blue circle on the screen for a period of time (it was probably about three to four seconds). I think in the course of a day it got really irritating.  So the add-in was uninstalled and people have been warry of it ever since. I recall there was this Red on/off button for it and as soon as you turned it on that was it (your day just got longer).

 

There are quire a few instances like that; small delays were people start looking for culprits. Kind of surprised Autodesk don't take a similar approach to Microsoft by now. In outlook etc. when an add-in takes up a lot of processing time it reports that and the user can understand where the time is spent (otherwise it is considered a Revit issue by default). I think in the MS Outlook case it is checking start-up time but in theory time spent executing particular DMU's could be considered by Revit over the course of a session.

Message 10 of 13

The primary reason at the moment is to force one of the updaters to run last. It's a new updater that is updating all construction data from cached SQL Server data. We are now only storing a primary key on a family or Fabrication Part. The construction data will be written to non user-modifiable, project bound, Shared Parameters. Gone will be the days of stale data stored in one of our 5000 rfa's and Fabrication Database. Our content manager is both happy and scared. 🙂

Message 11 of 13

Sounds interesting.  Similarly in theory we could avoid all information for COBie in Revit and just have keys. Then form the spreadsheet based on those keys and the information held elsewhere.

 

I often wonder about the history of keys and the information they point to however. When a key is stored it points to an item in a database but was that item defined in the database the same way as when later referenced with the key (you would expect not otherwise why have a key)? That is both the advantage and the disadvantage of it. It could be the historic information is lost and the key now points to misleading (since updated) version of the item in the database. When do you essentially need to define a new key, when is the product significantly different from what it was. Probably you have to keep the old information unchanged anyway for historic purposes.

Message 12 of 13

In our case the database Id's will persist indefinitely. A record may be set as obsolete, however.

 

We've been slowly turning the ship with regards to construction data for about 3 years. This sprint is the final adjustment.

It given us time to discover and adjust our needs and goals as a company and grow confident that this direction is the correct one.

At least until AU 2023 where everything will change! 🙂

Message 13 of 13

To better handle the situation where the count of items (IUpdaters) is odd it was better to implement a do...while loop.

 

 

public void SetExecutionOrder(List<IUpdater> updaters)
	{
		var last     = updaters[updaters.Count - 1];
		var lastLoop = false;
		var index    = 0;

		do
		{
			var current = updaters[index];  

			var next = updaters[index + 1];  

			lastLoop = next == last;  

			UpdaterRegistry.SetExecutionOrder(current.GetUpdaterId(), next.GetUpdaterId());

			index++;
		}
		while (lastLoop == false);
	}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community