Batch open and close documents may crashed the application?

Batch open and close documents may crashed the application?

comic3344
Enthusiast Enthusiast
2,333 Views
6 Replies
Message 1 of 7

Batch open and close documents may crashed the application?

comic3344
Enthusiast
Enthusiast

Dear all, 

 

I tried to batch open and close documents by API, and I write a sample as follow:

            #region batch open and close
            UIApplication app = commandData.Application;
            UIDocument uidoc = app.ActiveUIDocument;
            Document doc = uidoc.Document;
            string CurFileName = doc.PathName;
            string path = Interaction.InputBox("please input path1");
            string path2 = Interaction.InputBox("please input path2");
            DirectoryInfo pathdir = new DirectoryInfo(path);
            int i = 0;
            foreach (FileInfo fi in pathdir.GetFiles())
            {
                i = i + 1;
                UIDocument newUIdoc = app.OpenAndActivateDocument(fi.FullName);
                Document newdoc = newUIdoc.Document;
                doc.Close(false);
                doc.Dispose();
                uidoc.Dispose();

                Transaction transPara = new Transaction(newdoc);
                transPara.Start("openandsavetest");
                FamilyManager FM = newdoc.FamilyManager;
                FamilyParameter paraHello = FM.AddParameter("Hello", BuiltInParameterGroup.INVALID, ParameterType.Text, true);
                //FM.Set(paraHello, "world"); 
                transPara.Commit();

                SaveAsOptions saveopt = new SaveAsOptions();
                saveopt.Compact = true;
                saveopt.OverwriteExistingFile = true;
                newdoc.SaveAs(path2 + i.ToString() + ".rfa", saveopt);
                UIDocument tempuidoc1 = app.ActiveUIDocument;
                Document tempdoc1 = tempuidoc1.Document;
                newdoc.Dispose();
                uidoc = app.OpenAndActivateDocument(CurFileName);
                doc = uidoc.Document;
                tempdoc1.Close(false);
                tempdoc1.Dispose();
                tempuidoc1.Dispose();
            }
            #endregion

There are about thousands of .rfa files need to be operated. When about 400th file running, Revit is crashed. -_-

 

Please help me, thank you!

0 Likes
Accepted solutions (1)
2,334 Views
6 Replies
Replies (6)
Message 2 of 7

aignatovich
Advisor
Advisor
Accepted solution

Try to open document in background, e.g use Application.OpenDocumentFile instead of UIApplication.OpenAndActivateDocument.

 

And about your code, it is better to embrace in using instead of calling dispose

0 Likes
Message 3 of 7

adam.krug
Advocate
Advocate

If this is a run-out-of-memory issue then you also might consider using same variables instead of creating new inside every foreach iteration. So you declare saveAsOptions, newDocument, FM, paraHello etc. before the loop and just assign to it in every iteration. Yesterday I read an article about Unity development which explained that even though garbage collector does the job in .NET you might have memory issues if you allocate new memory over and over again in every foreach step.

 

Also I'm not sure what do you mean that revit crashed, if it crashes with some fatal error than ok, but if the UI is dead and it doesn't respond... I have one command that opens families, makes changes and reloads them to project which may take long, e.g. 15 minutes. I takes about 5 steps until Revit looks as if it is jammed completely, but as long as I'm not trying to intervene it will complete the task. In my solution there's a separate UI that can cancel the lengthy process if I want to, which could also be an option in your case.

Message 4 of 7

comic3344
Enthusiast
Enthusiast

Thank you very much for your reminder.  I will check all the variables in the loop again.

I mean the crash is fatal error, the VM is full and the RAM is OK.

 

0 Likes
Message 5 of 7

dante.van.wettum
Advocate
Advocate

As alternative you could hook into the idle event of revit.

I used this myself to make a batch exporter that exports around 200-250 files.

The idle event is triggered every time revit gets back into an idle state, so you are sure the last command you gave finished executing.

 

Do note: the idle event has some limitations on what is and isnt allowed. in some case you may need to simulate certain commands as externalevent as its not allowed from within the idle event.

 

        public Result OnStartup(UIControlledApplication a)
        {
            a.Idling += M_application_Idling;
        }

 

        private void M_application_Idling(object sender, IdlingEventArgs e)
        {
            if (useAddin == true)
            {
                UIApplication evenUI = sender as UIApplication;
                if (evenUI == null)
                    return;

                Autodesk.Revit.ApplicationServices.Application app = evenUI.Application;

                if (app != null)
                {
                    DoWork();
                }
            }
        }
Message 6 of 7

comic3344
Enthusiast
Enthusiast

Thank you for your reply.

app.Application.OpenDocumentFile(fi.FullName) may work in read-only situation.

0 Likes
Message 7 of 7

comic3344
Enthusiast
Enthusiast

Thank you!

 

I tried using app.appliction.openDocumentFile(fi.name);

 

Until now I've always credited that OpenAndActivateDocument method is the right way to open file with transaction.

 

Sorry!

0 Likes