Remote reflection в .NET runtime
Автор статьи — Сердар Курбанов SerdarKurbanov, основатель команды и ведущий разработчик Telescope.
При использовании программного обеспечения могут встречаться ситуации, когда приложение нельзя или нежелательно останавливать даже при возникновении неполадки. В таких ситуациях, когда использование отладчика невозможно, обнаружение ошибки может представлять нетривиальную задачу.
Ситуация может быть еще запутаннее, если приложение использует многопоточность. Определить какой именно из потоков вызвал ошибку может помочь логирование, но более универсальным решением была бы возможность взглянуть внутрь работающей программы и увидеть состояния объектов в ней, не останавливая ее. Одним из подходов к этой задаче может быть использование возможностей System.Reflection.
Решение с помощью Reflection
Рассмотрим применение Reflection для упомянутой проблемы — многопоточная программа работает некорректно, и нам требуются детали работы потоков в этой программе. Для моделирования такой ситуации создадим консольное приложение, в котором два потока синхронизуются с помощью System.Threading.ManualResetEventSlim. Один из потоков завершает выполнение раньше второго, и нам необходимо понять, какой из них опаздывает.
Теперь добавим в нашу программу класс, который будет отображать свойства объектов синхронизации с помощью Reflection.
Также добавим код, позволяющий отображать данные, полученные при помощи Reflection в окне браузера по запросу 127.0.0.1:20000
Запустив программу и запросив в браузере указанный адрес, мы увидим свойства наших объектов и поймем, что первый поток завершил работу, а второй еще нет.
Развитие идеи
Используя эту идею мы сделали приложение Telescope, которое Вы можете загрузить с flussig.org. Это программа для удаленного просмотра значений объектов в .NET-приложениях наподобие окна watch в Visual Studio, но позволяющая удаленно просматривать объекты без остановки программы. Решение состоит из двух частей — сборки TelescopeNode.dll, встраиваемой в Ваш проект и получающей данные об объектах с помощью Reflection, и программы Telescope.exe, играющей роль аггрегатора информации об отслеживаемых объектах и передающей информацию на браузер, где вы видите список объектов и их свойств.
B той же задаче об объектах синхронизации в многопоточном приложении можно привязаться к свойствам объектов с помощью такого кода:
В результате в окне браузера свойства объектов будут отображены в следующем виде:
Немного философии
Современная разработка старается использовать как можно более гибкие подходы и плотные связи между разработчиками, тестировщиками, менеджерами и клиентами — Agile и DevOps используются (явно или неявно) в большинстве команд разработчиков, создающих продукты для коммерческих компаний, поскольку это дает преимущества в скорости создания продуктов и приводит к большему удовлетворению конечных пользователей ПО. Гибкость определяется как работой менеджеров, так и программными средствами — ей способствует правильный выбор IDE, покрытие сценариев работы программы юнит-тестами, непрерывная интеграция.
Создав Telescope, мы надеемся добавить гибкости на уровень тестирования и отладки, дав возможность производить аналог отладки уже после релиза. Telescope может использоваться как последний рубеж обороны от ошибок (особенно для внутренних продуктов, к которым есть более легкий доступ) — когда программа уже запущена в релизе, но требуется контроль за состоянием некоторых объектов или определение источника уже совершившейся ошибки.