Что такое отладка? Точное определение вы можете найти в Google (или в ChatGPT — пишите в комментарии, если уже успели применить его для чего-то интересного или практического), я же напишу так, как понимаю сам. Отладка — процесс устранения неисправностей в программном коде: ошибок и некорректного поведения программы. Ошибки — это всё то, что вызывает исключения (неприятно) или фатальные ошибки с закрытием Revit (очень-очень неприятно). Некорректное поведение — это когда программа полностью исполняется, но финальный результат не совпадает с тем, что закладывает наш алгоритм.
Способы отладки
В этой части я опишу свой опыт, какие методы отладки я использовал в разное время. Использовать их я не советую, потому что они не всегда удобные и не совсем правильные. Если у вас мало времени, перематывайте к пункту "Отладка через Addin Manager".
Почему в макросе? Потому что его можно написать, запустить, поправить, запустить, и так до бесконечности. А подключенный плагин так исправить нельзя: нужно закрывать и открывать Revit, а это долго. Потом я переносил код в Visual Studio.
Как можно сделать:
Весь код оборачиваем в блок try, в блоке catch выводим сообщение с указанием строки, где была ошибка.
Я пока не рассказывал про обработку ошибок, если я напишу статью об этом, то добавлю ссылку, а пока можете кратко прочитать о ней здесь.
Выглядит это так:
Далее запустим макрос, но когда нам будет предложен выбор, нажмём Esc:
Ну и далее идём в строку 45 и устраняем ошибку.
2. Использование TaskDialog или вывод данных в файл
Если первый метод вполне рабочий, то этот метод я советую не использовать (разве что при ручной проверке работы на большом массиве данных, может быть удобно вывести всё в файл, чем смотреть в отладчике).
Этот способ нужен для устранения некорректной работы алгоритма. Итак, допустим, мы написали конструкцию if, и код внутри. Но код не исполняется. Тогда мы ставим в начале конструкции TaskDialog с сообщением "Код зашёл в if", и проверяем, зашёл он или нет. Если нет, то начинаем проверять условия, и например, с удивлением обнаруживаем, что сравнивая два одинаковых Element мы получаем false. Меняем сравнение с элементов на их Id, всё работает. Удаляем TaskDialog.
С выводом данных в файл чуть сложнее. Подробно о нём я расскажу в следующей статье. Тут смысл в чём: допустим, мы взяли коллекцию стен и всем элементам записываем что-то в параметр "Марка". Коллекция большая, код думает секунд 10 и выдаёт ошибку. Мы выводим в файл все Id данной коллекции, находим какой-то очень короткий Id, находим элемент в файле и понимаем, что забыли поставить WhereElementIsNotElementType() (и применили OfCategory() вместо OfClass(typeof(Wall)) ).
Отладка через Addin Manager
Visual Studio имеет в себе мощные инструменты отладки. Чтобы ими воспользоваться, нам надо сделать 2 вещи: расставить точки останова, и присоединиться к процессу Revit.exe.
Итак, порядок действий такой:
1. Пишем плагин, компилируем его, находим dll в папке bin/Debug
2. Запускаем Revit с установленным Addin Manager
3. В Visual Studio, находясь в плагине, написанном в пункте 1, жмём "Отладка" — "Присоединиться к процессу":
В появившемся окне выбираем Revit.exe
4. Загружаем dll из пункта 1 в Addin Manager:
5. Запускаем плагин кнопкой Run
Далее возможны 2 сценария отладки:
1. Мы не знаем где ошибка. Просто запускаем, при возникновении исключения нас перекинет в Visual Studio, где мы сможем посмотреть место, где оно возникло, а также значения всех переменных, созданных к моменту его возникновения.
Изучаем причины ошибки и устраняем их
2. Ставим точку останова (строка 34) на скрине выше. Для этого надо просто кликнуть по серому полю напротив интересующей нас строки.
Разберём тот же пример: код в блоке if не выполняется. Ставим точку останова на первой строке за блоком if и запускаем плагин. Если зашёл, то значит условие верное. Если нет, то неверное. Перед блоком if записываем отдельно значения входящих в условие переменных и в отдельную строку bool b = element1 == element2; ставим точку останова сразу за ними. Проверяем, смотрим значения. Видим, что element1 и element2 одинаковы, их одного документа и с одинаковым id, но значение b — false. Задумываемся о странностях такого поведения программы (на самом деле оно не странное, если мы получили эти два одинаковых элемента двумя разными путями, то для C# это разные элементы, потому что ссылки в памяти на них разные (подробнее про ссылочные и значимые типы), меняем сравнение Element на сравнение ElementId и получаем желаемый результат.
Подписывайтесь на мой телеграм-канал! До новых встреч!