es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo medir y registrar manualmente los tiempos de ejecución de todos los procedimientos almacenados de SQL Server (sin usar SQL Profiler)?

Estoy encargado de construir un panel de control para una aplicación de escritorio antigua (LDA). Esta fue construida en .NET Framework 2.0 y utiliza ADO.NET para acceder a la base de datos.

Fue instalada en la máquina local para muchos departamentos y usuarios internos. Tiene mil formularios y cada formulario tiene uno o varios botones que manipulan la base de datos llamando a un procedimiento almacenado de SQL Server.

El problema con LDA es que a veces, algunos departamentos o usuarios tienen problemas de lentitud o de respuesta lenta cuando presionan un botón. Queremos registrar todos los tiempos de ejecución de los procedimientos almacenados y ponerlos en un panel de control.

Usamos el perfilador de SQL Server pero no nos resultó útil ya que no mostraba qué departamento o usuario tenía una respuesta lenta. Así que estamos tratando de encontrar una solución agregando código de seguimiento a LDA (en la menor cantidad posible).

Tengo la idea de construir una clase envoltorio en SqlCommand o SqlConnection para medir el tiempo de ejecución de los procedimientos almacenados mediante un método de extensión como se muestra:

using(var connection = new MyCustomSqlConnection())
{
    ........
    // currentUserObject contiene toda la información del usuario y el departamento.
    myCustomSqlCommand.ExecutionQuery().TrackingTime(currentUserObject);
    .....
}

¿Es esto posible? ¿Tienen algún ejemplo?

No estoy familiarizado con el formulario de ventana, así que agradezco cualquier sugerencia basada en la clase / evento de Formulario / Botón que puedan tener.

¡Gracias y saludos cordiales!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución para crear un panel de control de monitorización para una aplicación de escritorio legada

    Como experto en IT especializado en sql-server, vb.net, winforms y ado.net, aquí está mi solución para crear un panel de control de monitorización para una aplicación de escritorio legada (LDA):

    Problema

    LDA fue creada en .NET Framework 2.0 y usa ADO.NET para acceder a la base de datos. Fue instalada en la máquina local de muchos departamentos y usuarios internos. Tiene mil formularios, cada formulario tiene 1- unos pocos botones que pueden manipular la base de datos llamando a procedimientos almacenados de SQL Server. El problema de LDA es que algunos departamentos, algunos usuarios se quedan colgados o hay una respuesta lenta cuando hacen clic en un botón.

    Solución

    Nos gustaría registrar todos los tiempos de ejecución del procedimiento almacenado y colocarlos en un panel de control de monitorización. Utilizamos SQL Server profiler, pero no nos ayuda porque no muestra en qué departamento, qué usuario se produjo una respuesta lenta. Así que estamos tratando de encontrar una solución añadiendo código de seguimiento a LDA (tan poco como sea posible).

    Mi solución ideal es construir una clase envolvente en SqlCommand o SqlConnection para medir el tiempo de ejecución del procedimiento almacenado por medio de un método de extensión como:

    using (var connection = new MyCustomSqlConnection())
    {
        ........
        // currentUserObject contiene toda la información del usuario y del departamento.
        myCustomSqlCommand.ExecutionQuery().TrackingTime(currentUserObject);
        .....
    }
    

    Aquí, MyCustomSqlConnection es una clase personalizada que extiende la clase SqlConnection y TrackingTime es un método de extensión personalizado que mide el tiempo de ejecución del procedimiento almacenado y hace un seguimiento de la información del usuario y del departamento.

    Para implementar esta solución, siga los pasos siguientes:

    1. Cree una nueva clase llamada MyCustomSqlConnection que extienda la clase SqlConnection.
    2. En la clase MyCustomSqlConnection, implemente un nuevo método personalizado llamado ExecutionQuery() que devuelve una nueva clase personalizada llamada MyCustomSqlCommand.
    3. Cree una nueva clase llamada MyCustomSqlCommand que extienda la clase SqlCommand.
    4. En la clase MyCustomSqlCommand, implemente un nuevo método de extensión personalizado llamado TrackingTime() que tome currentUserObject como parámetro y mida el tiempo de ejecución del procedimiento almacenado que se ejecuta mediante este objeto de comando.
    5. En el método TrackingTime(), haga un seguimiento de la información del usuario y del departamento junto con el tiempo de ejecución del procedimiento almacenado y guárdelo en una tabla de registro en la base de datos.
    6. Cree un nuevo formulario llamado MonitorDashboard que muestre los datos de la tabla de registro en un formato amigable para el usuario, como una tabla, gráfico o gráfico.
    7. Implemente un nuevo control temporizador en este formulario que actualice periódicamente los datos en la tabla de registro y actualice los componentes de la IU.

    Código de ejemplo

    Aquí hay un código de ejemplo para demostrar la implementación de las clases MyCustomSqlConnection y MyCustomSqlCommand:

    public class MyCustomSqlConnection : SqlConnection
    {
        public MyCustomSqlConnection() : base() { }
    
        public new MyCustomSqlCommand CreateCommand()
        {
            return new MyCustomSqlCommand(this);
        }
    }
    
    public class MyCustomSqlCommand : SqlCommand
    {
        public MyCustomSqlCommand(SqlConnection connection) : base()
        {
            this.Connection = connection;
        }
    
        public new MyCustomSqlDataReader ExecuteReader()
        {
            return new MyCustomSqlDataReader(base.ExecuteReader());
        }
    }
    
    public class MyCustomSqlDataReader : SqlDataReader
    {
        public MyCustomSqlDataReader(SqlDataReader reader) : base()
        {
            this.innerReader = reader;
        }
    
        private SqlDataReader innerReader;
    
        public override bool Read()
        {
            var start = DateTime.Now;
            var result = this.innerReader.Read();
            var end = DateTime.Now;
            var execTime = end - start;
    
            // Hacer un seguimiento del tiempo de ejecución, la información del usuario y del departamento en la tabla del registro.
            TrackExecutionTime(execTime, currentUserObject);
    
            return result;
        }
    
        private void TrackExecutionTime(TimeSpan execTime, User currentUserObject)
        {
            using(var connection = new SqlConnection(CONNECTION_STRING))
            using(var command = connection.CreateCommand())
            {
                // Insertar el tiempo de ejecución, la información del usuario y del departamento en la tabla del registro.
                command.CommandText = "INSERT INTO ExecutionLog (ExecTime, User, Department) VALUES (@ExecTime, @User, @Department)";
                command.Parameters.AddWithValue("@ExecTime", execTime.TotalMilliseconds);
                command.Parameters.AddWithValue("@User", currentUserObject.UserName);
                command.Parameters.AddWithValue("@Department", currentUserObject.DepartmentName);
                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }
    

    Aquí, la clase MyCustomSqlConnection crea un nuevo objeto MyCustomSqlCommand personalizado utilizando el método CreateCommand(). La clase MyCustomSqlCommand sobrescribe el método ExecuteReader() de la clase SqlCommand base y devuelve un nuevo objeto MyCustomSqlDataReader personalizado que hace un seguimiento del tiempo de ejecución e información del usuario para cada operación de lectura. La clase MyCustomSqlDataReader sobrescribe el método Read() de la clase SqlDataReader base y hace un seguimiento del tiempo de ejecución e información del usuario para cada operación de lectura mediante el método TrackExecutionTime() personalizado.

    Tenga en cuenta que este código es sólo un ejemplo para demostrar el concepto de la solución. Usted necesitará adaptarlo a sus requisitos específicos y detalles de implementación.

    Sugerencias

    Si no está familiarizado con el formulario de Windows, también puede considerar el uso de una solución de panel de control basado en web que se puede acceder desde cualquier dispositivo con un navegador web. Hay muchas bibliotecas y marcos de trabajo de terceros disponibles para .NET que pueden ayudarle a construir un panel de control de forma rápida y sencilla. Algunas opciones populares son:

    • DevExpress Dashboard
    • Telerik Dashboard
    • Syncfusion Dashboard
    • Infragistics Dashboard

    También puede considerar el uso de una solución basada en la nube para monitorizar y hacer un seguimiento del rendimiento de su aplicación de escritorio heredada. Hay muchos servicios de monitorización y análisis de aplicaciones basados en la nube disponibles que pueden proporcionar información en tiempo real sobre el rendimiento y el comportamiento del usuario de su aplicación. Algunas opciones populares son:

    • Microsoft Azure Application Insights
    • Amazon CloudWatch
    • Google Stackdriver
    • New Relic

    Estos servicios suelen requerir cambios mínimos en el código de su aplicación y pueden proporcionar métricas y análisis detallados para solucionar problemas de rendimiento y mejorar la experiencia del usuario.

Comments are closed.