Compartir vía


Contadores de rendimiento en SqlClient

Se aplica a: .NET Framework No compatible. .NET Core No compatible. .NET Standard

Descargar ADO.NET

Puede usar contadores de rendimiento de Microsoft.Data.SqlClient para supervisar el estado de la aplicación y los recursos de conexión que usa. Los contadores de rendimiento se pueden controlar con el Monitor de rendimiento de Windows pero también se puede tener acceso a ellos mediante programación usando la clase PerformanceCounter del espacio de nombres System.Diagnostics.

Contadores de rendimiento disponibles

Actualmente, hay 14 contadores de rendimiento distintos disponibles para Microsoft.Data.SqlClient, tal como se describe en la tabla siguiente.

Contador de rendimiento Descripción
HardConnectsPerSecond El número de conexiones por segundo que se establecen con un servidor de bases de datos.
HardDisconnectsPerSecond El número de desconexiones por segundo que se producen con un servidor de bases de datos.
NumberOfActiveConnectionPoolGroups El número de conjuntos de grupos de conexiones únicas que están activos. Este contador depende del número de cadenas de conexión única que haya en el AppDomain.
NumberOfActiveConnectionPools El número total de grupos de conexiones.
NumberOfActiveConnections El número de conexiones activas que se están utilizando actualmente. Nota: Este contador de rendimiento no está habilitado de manera predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
NumberOfFreeConnections El número de conexiones que se pueden utilizar en los grupos de conexiones. Nota: Este contador de rendimiento no está habilitado de manera predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
NumberOfInactiveConnectionPoolGroups El número de conjuntos de grupos de conexiones únicas que están marcados para ser eliminados. Este contador depende del número de cadenas de conexión única que haya en el AppDomain.
NumberOfInactiveConnectionPools El número de grupos de conexiones inactivas que no han tenido ninguna actividad recientemente y que están a la espera de ser eliminadas.
NumberOfNonPooledConnections El número de conexiones activas que no están agrupadas.
NumberOfPooledConnections El número de conexiones activas que administra la infraestructura de agrupación de conexiones.
NumberOfReclaimedConnections El número de conexiones que se han reclamado a través de la recolección de elementos no utilizados si la aplicación no llamó a Close o Dispose. Nota: No cerrar o eliminar explícitamente las conexiones afecta el rendimiento.
NumberOfStasisConnections El número de conexiones que están actualmente en espera de que se finalice una acción y que por lo tanto no pueden ser utilizadas por la aplicación.
SoftConnectsPerSecond El número de conexiones activas que se están extrayendo del grupo de conexiones. Nota: Este contador de rendimiento no está habilitado de manera predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
SoftDisconnectsPerSecond El número de conexiones activas que se devuelven al grupo de conexiones. Nota: Este contador de rendimiento no está habilitado de manera predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.

Activación de contadores desactivados de manera predeterminada

Los contadores de rendimiento NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond y SoftConnectsPerSecond están desactivados de forma predeterminada. Agregue la siguiente información al archivo de configuración de la aplicación para habilitarlos:

<system.diagnostics>  
  <switches>  
    <add name="ConnectionPoolPerformanceCounterDetail" value="4"/>  
    <!-- A value of 4 corresponds to System.Diagnostics.TraceLevel.Verbose -->
  </switches>  
</system.diagnostics>  

Recuperación de los valores de los contadores de rendimiento

La siguiente aplicación de consola muestra cómo recuperar valores de los contadores de rendimiento en su aplicación. Las conexiones deben estar abiertas y activas para que se devuelva la información de todos los contadores de rendimiento del proveedor de datos SqlClient de Microsoft para SQL Server.

Nota

En este ejemplo se usa la base de datos AdventureWorks de ejemplo. Las cadenas de conexión proporcionadas en el código de ejemplo suponen que la base de datos está instalada y disponible en el equipo local, y que ha creado inicios de sesión que coinciden con los proporcionados en las cadenas de conexión. Quizá deba habilitar inicios de sesión de SQL Server si su servidor se ha configurado usando la configuración de seguridad predeterminada, que solo admite la autenticación de Windows. Modifique las cadenas de conexión según sea necesario para su entorno.

Ejemplo

using System;
using Microsoft.Data.SqlClient;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PerformanceCounterTest
{
    class Program
    {
        PerformanceCounter[] PerfCounters = new PerformanceCounter[10];
        SqlConnection connection = new SqlConnection();

        static void Main()
        {
            Program prog = new Program();
            // Open a connection and create the performance counters.  
            prog.connection.ConnectionString =
               GetIntegratedSecurityConnectionString();
            prog.SetUpPerformanceCounters();
            Console.WriteLine("Available Performance Counters:");

            // Create the connections and display the results.  
            prog.CreateConnections();
            Console.WriteLine("Press Enter to finish.");
            Console.ReadLine();
        }

        private void CreateConnections()
        {
            // List the Performance counters.  
            WritePerformanceCounters();

            // Create 4 connections and display counter information.  
            SqlConnection connection1 = new SqlConnection(
                  GetIntegratedSecurityConnectionString());
            connection1.Open();
            Console.WriteLine("Opened the 1st Connection:");
            WritePerformanceCounters();

            SqlConnection connection2 = new SqlConnection(
                  GetSqlConnectionStringDifferent());
            connection2.Open();
            Console.WriteLine("Opened the 2nd Connection:");
            WritePerformanceCounters();

            SqlConnection connection3 = new SqlConnection(
                  GetSqlConnectionString());
            connection3.Open();
            Console.WriteLine("Opened the 3rd Connection:");
            WritePerformanceCounters();

            SqlConnection connection4 = new SqlConnection(
                  GetSqlConnectionString());
            connection4.Open();
            Console.WriteLine("Opened the 4th Connection:");
            WritePerformanceCounters();

            connection1.Close();
            Console.WriteLine("Closed the 1st Connection:");
            WritePerformanceCounters();

            connection2.Close();
            Console.WriteLine("Closed the 2nd Connection:");
            WritePerformanceCounters();

            connection3.Close();
            Console.WriteLine("Closed the 3rd Connection:");
            WritePerformanceCounters();

            connection4.Close();
            Console.WriteLine("Closed the 4th Connection:");
            WritePerformanceCounters();
        }

        private enum ADO_Net_Performance_Counters
        {
            NumberOfActiveConnectionPools,
            NumberOfReclaimedConnections,
            HardConnectsPerSecond,
            HardDisconnectsPerSecond,
            NumberOfActiveConnectionPoolGroups,
            NumberOfInactiveConnectionPoolGroups,
            NumberOfInactiveConnectionPools,
            NumberOfNonPooledConnections,
            NumberOfPooledConnections,
            NumberOfStasisConnections
            // The following performance counters are more expensive to track.  
            // Enable ConnectionPoolPerformanceCounterDetail in your config file.  
            //     SoftConnectsPerSecond  
            //     SoftDisconnectsPerSecond  
            //     NumberOfActiveConnections  
            //     NumberOfFreeConnections  
        }

        private void SetUpPerformanceCounters()
        {
            connection.Close();
            this.PerfCounters = new PerformanceCounter[10];
            string instanceName = GetInstanceName();
            Type apc = typeof(ADO_Net_Performance_Counters);
            int i = 0;
            foreach (string s in Enum.GetNames(apc))
            {
                this.PerfCounters[i] = new PerformanceCounter();
                this.PerfCounters[i].CategoryName = ".NET Data Provider for SqlServer";
                this.PerfCounters[i].CounterName = s;
                this.PerfCounters[i].InstanceName = instanceName;
                i++;
            }
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int GetCurrentProcessId();

        private string GetInstanceName()
        {
            //This works for Winforms apps.  
            string instanceName =
                System.Reflection.Assembly.GetEntryAssembly().GetName().Name;

            // Must replace special characters like (, ), #, /, \\  
            string instanceName2 =
                AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(', '[')
                .Replace(')', ']').Replace('#', '_').Replace('/', '_').Replace('\\', '_');

            // For ASP.NET applications your instanceName will be your CurrentDomain's
            // FriendlyName. Replace the line above that sets the instanceName with this:  
            // instanceName = AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(','[')  
            // .Replace(')',']').Replace('#','_').Replace('/','_').Replace('\\','_');  

            string pid = GetCurrentProcessId().ToString();
            instanceName = instanceName + "[" + pid + "]";
            Console.WriteLine("Instance Name: {0}", instanceName);
            Console.WriteLine("---------------------------");
            return instanceName;
        }

        private void WritePerformanceCounters()
        {
            Console.WriteLine("---------------------------");
            foreach (PerformanceCounter p in this.PerfCounters)
            {
                Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue());
            }
            Console.WriteLine("---------------------------");
        }

        private static string GetIntegratedSecurityConnectionString()
        {
            // To avoid storing the connection string in your code,  
            // you can retrieve it from a configuration file.  
            return @"Data Source=.;Integrated Security=True;" +
              "Initial Catalog=AdventureWorks";
        }
        private static string GetSqlConnectionString()
        {
            // To avoid storing the connection string in your code,  
            // you can retrieve it from a configuration file.  
            return @"Data Source=.;User Id=<myUserID>;Password=<myPassword>;" +
              "Initial Catalog=AdventureWorks";
        }

        private static string GetSqlConnectionStringDifferent()
        {
            // To avoid storing the connection string in your code,  
            // you can retrieve it from a configuration file.  
            return @"Initial Catalog=AdventureWorks;Data Source=.;" +
              "User Id=<myUserID>;Password=<myPassword>;";
        }
    }
}

Vea también