Python Node leads to revit crash

Hello Dynamo Friends :slight_smile:

I have a python code that runs without errors, all tasks are completed and at the end it shows a task dialog telling the user the run was successfull.
After klicking OK on the taskdialog, Dynamo starts loading, shows that the script is still running and then Revit crashes. Not on every run, but at most of the runs.

After 20 crashes I´m tired and out of ideas.
What can i do to find the problem? Appreciate any advice!

import io
import csv
import time
import clr
clr.AddReference("RevitAPI")
clr.AddReference('DynamoRevitDS')
clr.AddReference("RevitAPIUI")
import Dynamo
clr.AddReference('DSCoreNodes')
from Autodesk.Revit.UI import TaskDialog, TaskDialogCommonButtons, TaskDialogResult, TaskDialogCommandLinkId, TaskDialogIcon
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from datetime import datetime, timedelta

doc = DocumentManager.Instance.CurrentDBDocument
StartTimeItem = datetime.now()
StartTimeFormat = "%X"
StartDateformat = "%d.%m.%Y"
StartTime = StartTimeItem.strftime(StartTimeFormat)
StartDate = StartTimeItem.strftime(StartDateformat)

def QLOG_New_Entry():
	dynamoRevit = Dynamo.Applications.DynamoRevit()
	currentWorkspace = dynamoRevit.RevitDynamoModel.CurrentWorkspace
	dynamoFileName = currentWorkspace.FileName
	
	dynamoRevit = Dynamo.Applications.DynamoRevit()
	currentWorkspace = dynamoRevit.RevitDynamoModel.CurrentWorkspace
	dynamoFileName = currentWorkspace.FileName
	app = DocumentManager.Instance.CurrentUIApplication.Application
	User = app.Username
	
	now = datetime.now()
	dateformat = "%d.%m.%Y"
	timeformat = "%X"
	Date = now.strftime(dateformat)
	Time = now.strftime(timeformat)
	
	CentralFilePath_dfs = BasicFileInfo.Extract(doc.PathName).CentralPath
	CentralFilePath = "P:\\"+(CentralFilePath_dfs.split("\\dfs\\")[1])
	
	FileNameList = CentralFilePath.Split("\\")
	FileNameListLength = len(FileNameList)
	FileName = FileNameList [FileNameListLength-1]
	
	ProjectList = FileName.Split("_")
	Projectnumber = ProjectList[0]
	
	QLOG_New_Entry = Projectnumber+"\t"+User+"\t"+Date+"\t"+Time+"\t"+dynamoFileName
	return QLOG_New_Entry

def Read_SLOG():
	
	try:
		with io.open(SlogFilePath,"r", encoding = "utf-16(LE)") as SlogFile:	
			SLOG = SlogFile.read().splitlines()		
		return SLOG
	except:
		return "slog read error"
		
def Chop_SLOG():
	
	for slog in SLOG:
		if "STC" in slog:
			slog_Split = slog.Split(" ")
			slog_DateAndTimeString = slog_Split[1] + " " + slog_Split[2]
			slog_DateAndTimeObject = datetime.strptime(slog_DateAndTimeString, '%Y-%m-%d %H:%M:%S.%f')
			slog_CompareObject = datetime.now() - timedelta(minutes=500)						
			if slog_DateAndTimeObject > slog_CompareObject:						
				SLOG_Chop.append(slog)
	return SLOG_Chop

def Read_QLOG():
	try:
		with io.open(QlogFilePath,"r", encoding = "utf-8") as Qlogfile:	
			QLOG = Qlogfile.read().splitlines()
			return QLOG
	except:
		return "QLOG read error"
		
def Write_QLOG_START_Entry():
	
	QLOG_START_New = Read_QLOG()
	New_Entry = StartTime + "\tSTART\t"+ QLOG_New_Entry()
	QLOG_START_New.append(New_Entry)
	
	with io.open(QlogFilePath,"w", encoding="UTF8", newline='') as Qlogfile:	
		for Qlog in QLOG_START_New:
			writer = csv.writer(Qlogfile,delimiter="'")
			writer.writerow([Qlog])
	return QLOG_START_New
	
def Write_QLOG_END_Entry():
	
	QLOG_END_New = Read_QLOG()
	New_Entry = StartTime + "\tEND\t"+QLOG_New_Entry()
	QLOG_END_New.append(New_Entry)
	
	with io.open(QlogFilePath,"w", encoding="UTF8", newline='') as Qlogfile:	
		for Qlog in QLOG_END_New:
			writer = csv.writer(Qlogfile,delimiter="'")
			writer.writerow([Qlog])
	return QLOG_END_New

def UserMessage():

	taskDialog = TaskDialog("Test1")
	taskDialog.MainInstruction = "User currently syncing"#"Ein Benutzer synchronisiert gerade."
	taskDialog.MainContent = "Want to get queued in the sync line?"#"In Synchronisations-Warteschlange einreihen?"
	taskDialog.TitleAutoPrefix = False	
	taskDialog.MainIcon = TaskDialogIcon.TaskDialogIconInformation	
	taskDialog.CommonButtons = TaskDialogCommonButtons.Cancel | TaskDialogCommonButtons.Yes	
	taskDialog.FooterText = "Help"
	
	return taskDialog.Show()
	
def Sync():

	try:
		tOptions = TransactWithCentralOptions()
		rOptions = RelinquishOptions(False)
		rOptions.StandardWorksets = True
		rOptions.ViewWorksets = True
		rOptions.FamilyWorksets = True
		rOptions.UserWorksets = True
		rOptions.CheckedOutElements = True
		sOptions = SynchronizeWithCentralOptions()
		sOptions.SetRelinquishOptions(rOptions)
		sOptions.Compact = False
		sOptions.SaveLocalBefore = True
		sOptions.SaveLocalAfter = True
		sOptions.Comment = ""
		TransactionManager.Instance.ForceCloseTransaction()
		doc.SynchronizeWithCentral(tOptions, sOptions)
		return "Sync Successful"
	except:
		return "Sync did not work"

def WhileLoopSTC():
	timeout = time.time() + 120 #seconds
	bool_STC = True
	while bool_STC == True:
		time.sleep(1.0) # sleep for 1000 milliseconds
		if time.time() > timeout:
			bool_STC = False
			timeoutresultSTC = "timeout WhileLoopSTC"
			TimeoutResultSTC.append(timeoutresultSTC)
			break
		SLOG = Read_SLOG()
		SLOG_Sublist = SLOG[SLOG_LastItemIndex:]
		for slog in SLOG_Sublist:
			if "STC" in slog:
				Last_STC_Line = slog
				if Last_STC_Line[-4:] == "<STC":
					bool_STC = False		
				else:
					bool_STC = True		
			else:
				bool_STC = True
	return bool_STC,TimeoutResultSTC
	
def WhileLoopQLOG():
	timeout = time.time() + 120 #seconds
	bool = True
	while bool == True:
		time.sleep(1.0) # sleep for 1000 milliseconds
		if time.time() > timeout:
			bool = false
			timeoutresultQLOG = "timeout WhileLoopQLOG"
			TimeoutResultQLOG.append(timeoutresultQLOG)
			break
		QLOG = Read_QLOG()
		if [qlog for qlog in QLOG if all(i in qlog for i in [Projectnumber,qlog_StartTime,"END"])]:			
			bool = False
			QLOG_End_Line = qlog
			QLOG_End_Line_List.append(QLOG_End_Line)
		else:
			bool = True
	return bool, TimeoutResultQLOG, QLOG_End_Line_List

CentralFilePath_dfs = BasicFileInfo.Extract(doc.PathName).CentralPath
CentralFilePath = "P:\\"+(CentralFilePath_dfs.split("\\dfs\\")[1])
FileNameList = CentralFilePath.Split("\\")
FileNameListLength = len(FileNameList)
FileName = FileNameList [FileNameListLength-1]
SlogFileName = FileName.Replace("rvt","slog")
ProjectList = FileName.Split("_")
Projectnumber = ProjectList[0]
SlogFileFolder = CentralFilePath.Replace(".rvt","_backup")
SlogFilePath = SlogFileFolder+"\\"+SlogFileName
QlogFilePath = "......."

SLOG_Chop = []
Last_STC_Line_List = []
QLOG_Start_Line_List = []
QLOG_End_Line_List = []
TimeoutResultQLOG = []
TimeoutResultSTC = []
Bool = []
Bool_STC = [] 
SLOG = Read_SLOG()
SLOG_LastItemIndex = len(SLOG)-1
SLOG_Chop = Chop_SLOG()

if SLOG_Chop:
	for slog in SLOG_Chop:
		Last_STC_Line = slog
		if slog[-4:] == "<STC":
			SyncActive = False
		else:
			SyncActive = True
	Last_STC_Line_List.append(Last_STC_Line)
else:
	SyncActive = False
	
if SyncActive is False:
	QLOG_START_New = Write_QLOG_START_Entry()
	syncresult = Sync()
	syncmethod = "Synced with no active Sync"
	QLOG_END_New = Write_QLOG_END_Entry()

if SyncActive is True:
	QLOG = Read_QLOG()
	if [qlog for qlog in QLOG if all(i in qlog for i in [Projectnumber,StartDate,"START"])]:
		QLOG_Start_Line = qlog
		qlog_Split = qlog.Split("\t")
		qlog_StartTime = qlog_Split[0]
		result = WhileLoopQLOG()
		bool = result[0]
		QLOG_Start_Line_List.append(QLOG_Start_Line)
		Bool.append(bool)
	else:
		bool = False
		Bool.append(bool)
		
	if bool is False:
		result = WhileLoopSTC()
		bool_STC = result[0]
		timeoutresultSTC = result[1]
		TimeoutResultSTC.append(TimeoutResultSTC)
		Bool_STC.append(bool_STC)
	if bool_STC is False:
		QLOG_START_New = Write_QLOG_START_Entry()
		syncresult = Sync()
		syncmethod = "Synced after looping"
		QLOG_END_New = Write_QLOG_END_Entry()
		
TaskDialog.Show("Results", syncresult)

OUT = Last_STC_Line_List, SyncActive, QLOG_Start_Line_List, QLOG_End_Line_List, Bool, Bool_STC, TimeoutResultQLOG, TimeoutResultSTC, syncmethod

Edit: Changed title and description, it was not the dictionary that made things crash as i thought before.

Edit2: So the Problem seems to be the output, Revit crashes when the python node wants to generate the output for the node. The Problem also started after i used so many Lists as output. What can I do?

By adding one output after another i found the one causing the crash:

def WhileLoopSTC():
	timeout = time.time() + 120 #seconds
	bool_STC = True
	while bool_STC == True:
		time.sleep(1.0) # sleep for 1000 milliseconds
		if time.time() > timeout:
			bool_STC = False
			timeoutresultSTC = "timeout WhileLoopSTC"
			TimeoutResultSTC.append(timeoutresultSTC)
			break
		SLOG = Read_SLOG()
		SLOG_Sublist = SLOG[SLOG_LastItemIndex:]
		for slog in SLOG_Sublist:
			if "STC" in slog:
				Last_STC_Line = slog
				if Last_STC_Line[-4:] == "<STC":
					bool_STC = False		
				else:
					bool_STC = True		
			else:
				bool_STC = True
	return bool_STC,TimeoutResultSTC

if bool is False:
	result = WhileLoopSTC()
	timeoutresultSTC = result[1]
	TimeoutResultSTC.append(TimeoutResultSTC)

OUT = TimeoutResultSTC

And I see that i appended the variable to a list in the function, and later appended that variable again to the list, that was the problem, just had to remove the second appending.

1 Like