Guía de aplicación CodeSite de exploración en profundidad de Delphi
Aunque Delphi nos proporciona funciones de depuración extremadamente poderosas, encontrar errores sigue siendo una tarea ardua. Por lo general, el tiempo que dedicamos a escribir código y depurarlo es aproximadamente el mismo, o incluso más. Para reducir la pérdida innecesaria de tiempo y energía, a veces todavía necesitamos la ayuda de herramientas de depuración profesionales para mejorar la eficiencia del bloqueo de errores. En este artículo presentaremos la famosa herramienta de depuración CodeSite PRo 2.0 (ganó el segundo lugar en el premio Delphi Informant Readers' Choice Award 2000 a la mejor herramienta de depuración). Su sitio web oficial es www.raize.com. La función principal de CodeSite es permitir a los desarrolladores utilizar código para enviar detalles del tiempo de ejecución a receptores especiales para su posterior análisis. Más precisamente, a través de la clase TCodeSite implementada por CodeSite, podemos empaquetar y enviar información de tiempo de ejecución a CodeSite Dispatcher (el distribuidor de mensajes de CodeSite), que puede enrutar estos mensajes a uno o más receptores para su visualización. El receptor de mensajes predeterminado es CodeSite Viewer. La eficiencia de CodeSite se refleja en el hecho de que es diferente de un simple cuadro de diálogo que muestra mensajes o establece puntos de interrupción para verificar variables. Es más similar a la función de registro de eventos (Registro de eventos) que viene con Delphi. Es sin duda más poderoso que Event Log. Hay muchos y sus mensajes son sostenibles, es decir, se pueden guardar, lo que facilita el análisis retrospectivo. Antes de presentar el uso específico de CodeSite, primero echemos un vistazo a sus tres componentes. Objeto CodeSite Como se mencionó anteriormente, el envío de mensajes CodeSite desde una aplicación en ejecución se logra utilizando una instancia de la clase TCodeSite (definida en la unidad CSIntf). Simplemente podemos llamar al método de la clase TCodeSite. El mensaje se envía a CodeSite. Transportista. Por ejemplo, puede utilizar el método SendMsg del objeto para enviar un mensaje de cadena simple. El objeto TCodeSite implementa una gran cantidad de métodos para admitir varios tipos de envío de información sin ninguna conversión de datos. Por ejemplo, el método SendObject del objeto tiene dos parámetros: uno es la cadena del mensaje y el otro es una referencia a la instancia del objeto. Este método obtendrá el objeto. Todos los atributos publicados y luego empaquetarán la información de estos atributos en mensajes CodeSite. CodeSite Dispatcher En la mayoría de los casos, CodeSite Dispatcher se ejecutará silenciosamente en el área de la bandeja del sistema. Su única función es enrutar los mensajes CodeSite enviados desde varios objetos TCodeSite a sus destinos. De forma predeterminada, los mensajes de CodeSite se envían a CodeSite Viewer. Ni siquiera necesitamos iniciar CodeSite Dispatcher porque objetos como TCodeSite lo iniciarán automáticamente. La clase TCodeSite define una propiedad DestinationDetails que permite a los desarrolladores configurar cómo CodeSite Dispatcher enruta los mensajes CodeSite enviados a diferentes destinos, como archivos de registro. Pero normalmente no es necesario modificar esta propiedad. CodeSite Viewer Aunque CodeSite admite el envío de mensajes a diferentes destinos, en la mayoría de los casos CodeSite Viewer es el principal destino de envío. Incluso cuando se envía a otros destinos, como archivos de registro u otra máquina, CodeSite Viewer sigue siendo la herramienta principal para ver y analizar mensajes. CodeSite Viewer consta de los siguientes cuatro paneles: lista de mensajes, visor de mensajes, pila de llamadas y panel Scratch. El espacio de trabajo principal de CodeSite Viewer es la lista de mensajes, que se utiliza para mostrar todos los mensajes enviados al Visor o los mensajes cargados desde archivos de registro. Los visores de mensajes se utilizan para ver información adicional asociada con los mensajes. Por ejemplo, si el mensaje actual se envía mediante el método SendObject, el visor de mensajes mostrará los valores actuales de todas las propiedades publicadas del objeto. El panel de pila de llamadas muestra una vista de pila basada en mensajes csmEnterMethod. Los paneles Scratch se utilizan para mostrar información no sostenible. El panel Scratch es muy útil cuando queremos rastrear cierta información pero no queremos registrarla en el registro de mensajes, como cuando queremos ver una gran cantidad de mensajes repetidos como la posición actual del mouse. En este momento podemos usar el método WritePoint del objeto TCodeSite y especificar el parámetro ID de línea para especificar el número de líneas del panel borrador utilizadas para acomodar la información del mouse. Usemos un ejemplo simple para demostrar cómo enviar un mensaje a CodeSite Viewer desde el programa: (1) Cree un nuevo proyecto y luego cambie el panel de componentes a la página CodeSite (CodeSite instalará dos componentes en el sistema después de la instalación TCSGlobalObject y TCSObject). Seleccione el componente TCSGlobalObject y colóquelo en el formulario. El componente TCSGlobalObject proporciona interacción en tiempo de diseño con el objeto TCodeSite global (el TCodeSite global se inicializa en la unidad CSInft). (2) Agregue un botón y luego escriba el siguiente código en su evento OnClick: //CodeSite es el objeto TCodeSite global CodeSite.SendMsg('primer mensaje de CodeSite'); (3) Compile y ejecute este programa simple. Haga clic en el botón después de ejecutar y se ejecutarán CodeSite Dispatcher y CodeSite Viewer. Al mismo tiempo, verá los mensajes enviados por el programa en la lista de mensajes de CodeSite Viewer (nota: no necesitamos iniciar CodeSite Dispatcher y CodeSite Viewer antes de ejecutar el programa, porque el objeto TCodeSite los iniciará automáticamente cuando necesita enviar mensajes). Los resultados de la ejecución se muestran en la Figura 4.38 a continuación:
(4) A continuación, detenga el programa y agregue el siguiente código en el proceso de manejo de eventos OnClick: CodeSite.SendObject('Form1', Form1); (5) Vuelva a compilar y ejecutar el programa, haga clic en el botón nuevamente, esta vez estará. En CodeSite Viewer vi dos mensajes. El mensaje correspondiente a Form1 incluye la información del objeto de Form1. (6) Para ver la información del objeto asociado de Form1, seleccione el comando de menú CodeSite Viewer Ver|Inspector para mostrar un nuevo panel en el lado derecho de la lista de mensajes, en el que se muestran los atributos publicados de Form1, como se muestra en Figura 4.39 a continuación:
(7) Detenga el programa nuevamente y luego modifique el código en el proceso OnClick de la siguiente manera: CodeSite.EnterMethod('Button1Click'); CodeSite.SendMsg('primer mensaje de CodeSite'); ; CódigoSite .ExitMethod('Botón1Clic'); (8) Esta vez, cuando ejecutamos el programa y hacemos clic en el botón, veremos que los mensajes "Primer mensaje de CodeSite" y "Form1" están sangrados entre los mensajes "Button1Click", como se muestra en la Figura 4.40 a continuación:
Al agregar llamadas a los métodos EnterMethod y ExitMethod, podemos generar un registro para registrar cuándo se llaman los métodos. Después de mirar los ejemplos, encontraremos que la función de CodeSite es muy poderosa. Podemos generar información muy detallada simplemente agregando algunas declaraciones al programa y mostrándola en gráficos vívidos a través de CodeSite Viewer. A continuación, hablemos de la tecnología de aplicaciones avanzada de CodeSite. Envío de mensajes a archivos de registro Cada programa tendrá más o menos errores. Si no sucede en este momento, sucederá en ese momento. Si no sucede en poco tiempo, puede suceder después de mucho tiempo. A veces sucede repetidamente y otras veces sucede de manera muy accidental. Si una persona te dice que los programas que escribe se ejecutan sin problemas en cualquier momento, está mintiendo. Es precisamente debido a la naturaleza accidental y oculta de los errores que a menudo nos resulta difícil repetir los errores enviados por los usuarios, lo que crea un gran obstáculo para que podamos depurar el programa y encontrar la causa del problema, y CodeSite puede enviar mensajes. para registrar archivos. Esto facilita a los usuarios informar errores, ya que solo necesitan enviar el archivo de información generado durante el tiempo de ejecución. En consecuencia, nuestro trabajo de depurar el programa será más fácil. Podemos utilizar CodeSite Viewer para analizar intuitivamente la causa y la ubicación del error. Para cambiar el destino del envío de mensajes, podemos hacerlo configurando la propiedad DestinationDetails del objeto TCodeSite. Esta característica requiere que CodeSite Dispatcher esté instalado en la máquina del cliente, que es una parte de CodeSite que se puede distribuir gratuitamente. El proceso específico a continuación todavía se basa en el ejemplo mencionado anteriormente: (1) Agregue el siguiente código al evento OnCreate del formulario: CodeSite.DestinationDetails := 'File[Path=C:/FirstLog.csl]' (2) Compile y ejecute el programa. Esta vez, después de hacer clic en el botón, el mensaje ya no se envía al CodeSite Viewer sino al archivo FirstLog.csl en la unidad C. (3) Utilice CodeSite Viewer para cargar el archivo FirstLog.csl. Esta vez vemos los mensajes de CodeSite guardados como antes. (4) Si queremos enviar mensajes a CodeSite Viewer y archivos de registro al mismo tiempo, simplemente modifique el código anterior a: CodeSite.DestinationDetails := 'Viewer,File[Path=C:/FirstLog.csl]'; -Datos personalizados Aunque la clase TCodeSite proporciona una gran cantidad de métodos para procesar diferentes tipos de datos, a veces es posible que necesitemos enviar información de datos en un determinado formato personalizado. Con este fin, la clase TCodeSite define el método SendCustomData, que admite el envío de cualquier tipo de datos y formatea los datos de acuerdo con un formateador personalizado para que CodeSite Viewer pueda mostrar los datos correctamente. Primero necesitamos crear una subclase del objeto TCSFormatter y luego sobrecargar los métodos FormatData, InspectorType y TypeName del objeto. Luego llame al objeto del administrador de objetos CodeSite CSObjectManager para registrar la nueva subclase TCSFormatter. Además, también necesitamos llamar al método RegisterCustomFormat para registrar un nuevo tipo de mensaje. El siguiente es un ejemplo de aplicación práctica. Un formateador personalizado del tipo de registro TCSEmployeeRecord se implementa en la unidad CSEmployee.pas: la interfaz de la unidad CSEmployee utiliza Windows, Gráficos, CSIntf const csmEmployeeSummary = csmUser + 1; , en la sección Usos agrega una referencia a la unidad CSIntf. El segundo paso es definir nuevas constantes de tipo de mensaje CodeSite para cada formateador. Arriba definimos dos constantes. Tenga en cuenta que las constantes deben ser mayores que csmUser, pero no mayores que 32.000. escriba TCSEmployee = registrar Apellido: cadena; Nombre: cadena; Fecha de contratación: Días de vacaciones: Entero; Booleano; fin; El registro anterior es el tipo de datos personalizado que queremos enviar. TCSEmployeeSummaryFormatter = clase (TCSFormatter) función pública Tipo de inspector: anulación de datos de función (var datos); Arriba están las definiciones de dos clases de formateador personalizado. El primer formateador formateará el registro de TCSEmployee en un formato de texto, y el segundo formateador formateará el registro de TCSEmployee en un estilo de cuadrícula. la implementación utiliza SysUtils {==========================================} {= = Métodos TCSEmployeeSummaryFormatter ==} {===========================================} función TCSEmployeeSummaryFormatter .InspectorType: TCSInspectorType comenzar Resultado: = itStockStringList; El primer paso para implementar un formateador personalizado es determinar qué tipo de visor integrado se utilizará para ver los datos formateados. En este caso, se utiliza un visor de lista de cadenas. El tipo de visor será utilizado por el método FormatData. procedimiento TCSEmployeeSummaryFormatter.FormatData (var Datos); ', ' + EmpRec.Estado + ' ' + EmpRec.ZipCode); AddLine( ''); AddLine( 'Teléfono: ' + EmpRec.PhoneNumber ); AddLine( 'Fecha de contratación: ' + DateToStr( EmpRec.HireDate ) ); m', [ EmpRec.Salary ] ) ); AddLine( '' ); AddLine( 'Días de vacaciones: ' + IntToStr( EmpRec.VacationDays ) ); AddLine( 'Días de enfermedad: ' + IntToStr( EmpRec.SickDays ) ); si EmpRec.Manager entonces AddLine( 'Administrador: Sí' ) else AddLine( 'Administrador: No' ); ; El método FormatData es la parte principal. Tenga en cuenta que el parámetro de datos pasado al método FormatData es un parámetro variable sin tipo. Esto significa que este parámetro puede ser de cualquier tipo de datos. Mediante el proceso de registro de formato, podemos garantizar que el tipo forzado se asigne a un registro de datos personalizado sin errores de conversión. Después de convertir el tipo de datos, podemos formatear los datos. Aquí usamos el método AddLine de la clase base TCSFormatter para agregar líneas divisorias entre cadenas para formatear. función TCSEmployeeSummaryFormatter.TypeName: string; comenzar Resultado := 'TCSEmployee end'; la sobrecarga del método TypeName es opcional, pero normalmente podemos usarlo para devolver la cadena que aparece en la lista de mensajes. {=========================================} {== Métodos TCSEmployeeDetailsFormatter == } {==========================================} función TCSEmployeeDetailsFormatter.InspectorType: TCSInspectorType ; comenzar Resultado: = itStockGrid; Para el formateador de detalles de los empleados, se utilizará el visor de cuadrícula nombrado para ver los datos: procedimiento TCSEmployeeDetailsFormatter.FormatData( var Data ); var EmpRec: TCSEmployee; begin EmpRec := TCSEmployee( Data ); ; AddNameValuePair( 'Nombre', EmpRec.Nombre); AddNameValuePair( 'Dirección', EmpRec.Address ); AddNameValuePair( 'Ciudad', EmpRec.City ); AddNameValuePair( 'Número de teléfono'; EmpRec.PhoneNumber ); AgregarNombreValuePair( 'HireDate', EmpRec.HireDate); AddNameValuePair( 'Salario', Formato( '%m', [ EmpRec.Salary ] ) ); AddNameValuePair( 'VacationDays', EmpRec.VacationDays ); ); AddNameValuePair( 'Administrador', EmpRec.Manager); end; Aquí para formatear los datos en el visor de cuadrícula, utilizamos el método AddNameValuePair. función TCSEmployeeDetailsFormatter.TypeName: cadena; comenzar Resultado := 'TCSEmployee end'; =============} {== Métodos de soporte ==} {=======================} procedimiento CSSendEmployeeSummary ( const Mensaje: cadena; EmpRec: TCSEmployee); comenzar CodeSite.SendCustomData (csmEmployeeSummary, Msg, EmpRec); finalizar el procedimiento CSSendEmployeeDetails (const Msg: string; EmpRec: TCSEmployee); Finalmente, no olvide llamar al método CSObjectManager.RegisterCustomFormatter para registrar el formateador en CodeSite Object Manager. inicialización CSObjectManager.RegisterCustomFormatter (csmEmployeeSummary, TCSEmployeeSummaryFormatter); CSObjectManager.RegisterCustomFormatter (csmEmployeeDetails, TCSEmployeeDetailsFormatter);