Loading a rfa file into a document using LoadFamily() freezes Revit UI

Loading a rfa file into a document using LoadFamily() freezes Revit UI

Kennan.Chen
Advocate Advocate
3,531 Views
19 Replies
Message 1 of 20

Loading a rfa file into a document using LoadFamily() freezes Revit UI

Kennan.Chen
Advocate
Advocate

Hi,

    I have encountered a problem while using the Document.LoadFamily() api to load an rfa file into Revit 2019 and Revit 2020. The problem can cause the ribbon UI to freeze until manually moving the mouse to any ribbon button or just resizing the revit window. The problem occurs only when the rfa file is created by an old version of revit which means somehow the upgrade process freezes the revit ribbon UI.

    Actually I can reproduce this problem by loading a family manually from the Revit UI. If you want to give a try, remember to move the mouse to the ribbon tabs after loading the rfa. The tab background won't change when the mouse enters which means the ribbon UI is frozen.

    If I want to show a WPF window right after the rfa file was loaded. This problem can cause the content of the window not to be rendered because the UI thread was somewhere stuck. Resizing the WPF window can make the content rendered. One thing to mention that winform is not affected by this problem maybe because the gdi engine. 

    Actually this problem was first encountered on Revit 2016-2018, and I found an api(RibbonControlService.updateLayout()) in UIFrameworkServices.dll. I call this api right after the family was loaded, everything was fine. But it just doesn't work in Revit 2019 and Revit 2020.

    Things I have already tried by not working:

  1. Use the Dispatcher to show the Window with a higher priority.
  2. Resize the window with code right after the window is loaded.
  3. Use the win32 api to resize the WPF window and the Revit main window.
  4. Set the QuickAccessBar to blow ribbon and then set it back wishing to cause the UI to update.
  5. RibbonControlService.updateLayout() as I have mentioned.
  6. ComponentManager.Ribbon.UpdateLayout().

    I made a short demo to reproduce this problem. The button in the center of the TestWindow doesn't show up. Can anybody give a help?

    [Transaction(TransactionMode.Manual)]
    public class LoadFamilyCommand : IExternalCommand
    {
        #region Interface Implementations

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var document = commandData.Application.ActiveUIDocument.Document;
            var ofd      = new OpenFileDialog();
            var result   = ofd.ShowDialog();
            if (result.HasValue && result.Value)
            {
                using (var transaction = new Transaction(document, "Load Family"))
                {
                    transaction.Start();
                    document.LoadFamily(ofd.FileName);
                    transaction.Commit();
                }

                RibbonControlService.updateLayout();
                new TestWindow().ShowDialog();
            }

            return Result.Succeeded;
        }

        #endregion
    }

    public class TestWindow : Window
    {
        #region Constructors

        public TestWindow()
        {
            InitializeComponents();
        }

        #endregion

        #region Others

        private void InitializeComponents()
        {
            var grid = new Grid();
            var button = new Button
                         {
                             Content             = new TextBlock {Text = "Click Me"},
                             VerticalAlignment   = VerticalAlignment.Center,
                             HorizontalAlignment = HorizontalAlignment.Center
                         };
            grid.Children.Add(button);
            Content = grid;
        }

        #endregion
    }
3,532 Views
19 Replies
Replies (19)
Message 2 of 20

Kennan.Chen
Advocate
Advocate

More info:

When the Visual Studio debugger is attached to Revit, the problem gone.

Message 3 of 20

Kennan.Chen
Advocate
Advocate

After days of exploring, and with no replies from this forum, I finally gave up.

I truly believe that this problem is caused by Revit internally. Nothing I can do to wake up the UI thread. In my case I just want to show up a WPF window to ask the user to select one of the family types defined in the loaded family. I end up with a workaround that uses an individual process to show the window and the window process communicates with Revit process with a named pipe IPC tunnel. But the user still cannot survive from the freezing Ribbon UI.

Hope one day Revit team can fix this!

Message 4 of 20

Anonymous
Not applicable

Unfortunately, I have the same problem. I hope the bug will be fixed.

0 Likes
Message 5 of 20

Sean_Page
Collaborator
Collaborator

Hard to tell since this is just a snip of.code, but appears to me that the result /closure of the form is never returned so the Command will complete.

 

Check for the DialogResult and the return Result based on that.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes
Message 6 of 20

cwaluga
Advocate
Advocate

If anyone is not returning correctly it is Revit’s own conversion dialog, which implicitly triggers while loading a family that has not yet been upgraded. I can confirm that this annoying bug happens whether there is another dialog involved or not. We convert all families anyway, but we regularly observe the same before migrating all families to a new Revit version.

0 Likes
Message 7 of 20

mcbubble
Participant
Participant

This problem still exists in Revit 2021. I have been trying for days to find a workaround. We show progress animations when calling LoadFamily, but after the first call, when a family needs to be converted and the stupid, senseless dialog pops up and closes the WPF rendering is frozen. As already mentioned it stays frozen even for the next dialog we open after loading. When the user moves the mouse to anywhere, that show a tooltip or resizes the window the UI comes back. 

I did a lot of reverse engineering to understand what's going on and it appears Revit is doing something which is causing the WPF render thread to die. There can be multiple UI-threads in WPF, but there's only one render thread. I couldn't find how the render thread is restarted with a tooltip or resizing, but much better would be Revit wouldn't cause WPF to freeze. It might even be sufficient to not show the conversion dialog.

Message 8 of 20

cwaluga
Advocate
Advocate

We observed that you can get Revit back when you double click the Ribbon multiple times. This is not something which I would like to tell our customers. For us the only solution was converting our families in batch, also to keep loading times low.

 

Given that nothing (much) has changed for families in the last couple of years, it would be great if family conversion was not necessary in the first place. I really don't know what this process even does - other than incrementing a version number, adding some metadata and creating a backup file. This should be done in milliseconds. I bet showing the faulty progress window eats up most of the conversion time for families.

0 Likes
Message 9 of 20

FaustoMendezcom
Enthusiast
Enthusiast

I run into this issue today, here is a quick & dirty "fix".

 

if you show a ballon tip. after your are done with LoadFamily it will unfreeze the UI.

        public static void ShowBalloonTip(string msg) {
          Autodesk.Internal.InfoCenter.ResultItem ri = new Autodesk.Internal.InfoCenter.ResultItem();
          ri.Title = msg;
          // showing ballon tip for the shortest amount of time.
          Autodesk.Windows.ComponentManager
            .InfoCenterPaletteManager.Configuration.BalloonDisplayPeriod = 1;
          // Max transparency for the LoadFamily fix to work.
          Autodesk.Windows.ComponentManager
            .InfoCenterPaletteManager.Configuration.BalloonTransparency = 80;
          Autodesk.Windows.ComponentManager
            .InfoCenterPaletteManager.ShowBalloon(ri);
        }

 

 ShowBalloonTip("Family Updated");

 

It looks like this with transparency set to 80. on the top right corner. 

FaustoMendezcom_0-1615326158198.png

 

 here is more info about Balloon tips. Using .NET Balloon Tips in a Revit Add-in 

Hope it helps 🙂
-------------------------------------------------------------------------------------
www.faustomendez.com
Message 10 of 20

mcbubble
Participant
Participant

Amazing, showing a bubble does work to unfreeze the UI. Thanks for the idea @FaustoMendezcom.

I am surprised that not a lot more people run into the same problem, in particular Revit themselves, since they also use WPF in their code. e.g. the docking window control, AvalonDock. Somehow makes me wonder if there's another way to call LoadFamily which avoids the UI freeze. Maybe no one needs to load families from older versions, but we have hundreds of families which the users can select from.

0 Likes
Message 11 of 20

Sean_Page
Collaborator
Collaborator

I have used your test code as well as your "manual UI approach" in Revit 2020 and I can not recreate the issue in either case. The button on the form is display almost immediately no matter how old of a family I use ('14,'16,'18) nor does  my ribbon freeze when manually importing a family. Is there any chance you have an updater or event handler that may be trying to do something with the loaded family?

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes
Message 12 of 20

Kennan.Chen
Advocate
Advocate

It's such a surprise to see you guys are still watching this issue.


This solution looks quite amazing, and better than my multi-process solution. I'll give a try later.

 

Hope someone can post this framework-level issue to Revit team to make it fixed internally.

0 Likes
Message 13 of 20

Kennan.Chen
Advocate
Advocate

That's a new direction. I'll try and see if I can reproduce it in a clean environment.


@Sean_Page wrote:

I have used your test code as well as your "manual UI approach" in Revit 2020 and I can not recreate the issue in either case. The button on the form is display almost immediately no matter how old of a family I use ('14,'16,'18) nor does  my ribbon freeze when manually importing a family. Is there any chance you have an updater or event handler that may be trying to do something with the loaded family?

 


 

0 Likes
Message 14 of 20

mcbubble
Participant
Participant

Are you running it from the debugger on your system there? Usually doesn't happen in the debugger, although I have a reproduceable case with the debugger attached. 

0 Likes
Message 15 of 20

Sean_Page
Collaborator
Collaborator

Nope. That is a regular session of Revit, just running the code from my "test" button on one of our addins.

 

Here is the code that I am using for it:

[Transaction(TransactionMode.Manual)]
    class Test : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Document document = commandData.Application.ActiveUIDocument.Document;
            OpenFileDialog ofd = new OpenFileDialog();
            if(ofd.ShowDialog() == DialogResult.OK)
            {
                using(var transaction = new Transaction(document, "Load Family"))
                {
                    transaction.Start();
                    document.LoadFamily(ofd.FileName);
                    transaction.Commit();
                }
                new TestWindow().ShowDialog();
            }
            return Result.Succeeded;
        }
    }

    public class TestWindow : Window
    {
        public TestWindow()
        {
            InitializeComponents();
        }
        private void InitializeComponents()
        {
            var grid = new System.Windows.Controls.Grid();
            var button = new System.Windows.Controls.Button
			{
                Content = new TextBlock { Text = "Click Me" },
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Center
            };
            grid.Children.Add(button);
            Content = grid;
        }
    }
Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes
Message 16 of 20

jmlovelace
Enthusiast
Enthusiast

Resurrecting this thread as it seems to be the closest match to a problem I'm experiencing. I am running a WinForms UI with embedded WebView2, so that I can use web frameworks like Vue to write my UI and have it communicate to Revit using Revit.Async (Kennan I think this is your wrapper package, right?) 

 

I've ran into an odd scenario where I need to load a Family using the doc.LoadFamily method. Works fine if the family does not need upgrading but if it does it will upgrade and load then seemingly locks the UI like you described. If I close my WinForms window and try to reload, WebView2 does not initialize. And, even more oddly, if I try to post any messages back to Revit after the family load using window.chrome.webview.postmessage, none of the messages are getting received by the WebView instance.

0 Likes
Message 17 of 20

nick-graham
Explorer
Explorer

@jmlovelace Wanted to reply to say I am experiencing this exact same issue, but with a WPF hosted WebView2.

 

I started a new topic for it here: 
https://forums.autodesk.com/t5/revit-api-forum/loading-amp-upgrading-a-family-via-doc-loadfamily-fro... 

 

Message 18 of 20

jmlovelace
Enthusiast
Enthusiast

For what it’s worth, the only workaround I could find for my use case was to just only load families in the current revit version so the upgrade dialog is not triggered. I used Design Automation to create a script that would auto upgrade families from our library to the current version before importing

Message 19 of 20

Songohu_85
Enthusiast
Enthusiast

I always used different way to load family from file into project document and never experienced any issues:

		public void LoadFamily()
		{
			OpenFileDialog dialog = new OpenFileDialog();
			var result = dialog.ShowDialog();
			if(result == DialogResult.OK)
			{
				Document famDoc = Application.Application.OpenDocumentFile(dialog.FileName);
				famDoc.LoadFamily(Application.ActiveUIDocument.Document, new FamilyLoadOptions());
				famDoc.Close(false);
			}		
		}
		
	    class FamilyLoadOptions : IFamilyLoadOptions
	    {
	        public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
	        {
	            overwriteParameterValues = true;
	            return true;
	        }
	
	        public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
	        {
	            source = FamilySource.Project;
	            overwriteParameterValues = false;
	            return true;
	        }
	    }
0 Likes
Message 20 of 20

NonicaTeam
Enthusiast
Enthusiast

I also experienced this issue when running within a Python node (Dynamo) in Revit 2023(no point release) and Windows 11 (no message was shown as Exception btw). Below the code. It seems to run well and after trying to interact, Revit is frozen and enters an endless loading loop.

def loadFamily(path):
    try:
        resp = False
        with Transaction(doc, "LoadFamily") as t:
            t.Start()
            fam_sym = clr.Reference[FamilySymbol]()
            loaded = doc.LoadFamilySymbol(path, "MyFamilyName", fam_sym)
            if loaded and fam_sym.IsActive == False:
                fam_sym.Activate()
            t.Commit()
    except Exception as e:
        Autodesk.Revit.UI.TaskDialog.Show("Error", str(e) + " - " + str(sys.exc_info()[-1].tb_lineno))

 

0 Likes