Partager via


Compteurs de performances dans SqlClient

S’applique à : .NET Framework

Télécharger ADO.NET

Vous pouvez utiliser des compteurs de performances Microsoft.Data.SqlClient pour surveiller l’état de votre application et les ressources de connexion qu’elle utilise. Vous pouvez surveiller les compteurs de performance à l'aide de l'Analyseur de performances Windows ou accéder à ces derniers par programme à l'aide de la classe PerformanceCounter dans l'espace de noms System.Diagnostics.

Important

L’approche PerformanceCounterbasée sur la base décrite dans cet article nécessite .NET Framework et s’exécute uniquement sur Windows. La System.Diagnostics.PerformanceCounter classe n’est pas disponible dans les plateformes .NET Core, .NET 5+ ou non Windows. Pour la supervision multiplateforme dans les applications .NET modernes, utilisez plutôt des compteurs d’événements dans SqlClient .

Compteurs de performances disponibles

Actuellement, il existe 14 compteurs de performances différents disponibles pour Microsoft.Data.SqlClient, comme décrit dans le tableau suivant.

Compteur de performances Description
HardConnectsPerSecond Nombre de connexions par seconde qui sont établies à un serveur de base de données.
HardDisconnectsPerSecond Nombre de déconnexions par seconde qui sont effectuées à un serveur de base de données.
NumberOfActiveConnectionPoolGroups Nombre de groupes du pool de connexion unique qui sont actifs. Ce compteur est contrôlé par le nombre de chaînes de connexion uniques qui se trouvent dans AppDomain.
NumberOfActiveConnectionPools Nombre total de pools de connexions.
NumberOfActiveConnections Nombre de connexions actives en cours d'utilisation. Note: Ce compteur de performances n’est pas activé par défaut. Pour activer ce compteur de performance, voir Activation des compteurs désactivés par défaut.
NumberOfFreeConnections Nombre de connexions disponibles pour une utilisation dans les regroupements de connexions. Note: Ce compteur de performances n’est pas activé par défaut. Pour activer ce compteur de performance, voir Activation des compteurs désactivés par défaut.
NumberOfInactiveConnectionPoolGroups Nombre de groupes uniques de pools de connexions qui sont marqués pour l'élagage. Ce compteur est contrôlé par le nombre de chaînes de connexion uniques qui se trouvent dans AppDomain.
NumberOfInactiveConnectionPools Nombre de pools de connexions inactifs sans activité récente et en attente de suppression.
NumberOfNonPooledConnections Nombre de connexions actives qui ne sont pas regroupées.
NumberOfPooledConnections Nombre de connexions actives qui sont gérées par l'infrastructure de regroupement de connexions.
NumberOfReclaimedConnections Nombre de connexions qui ont été récupérées via le ramasse-miettes où Close ou Dispose n'ont pas été appelés par l’application. Remarque Ne pas fermer ou supprimer explicitement les connexions pénalise la performance.
NumberOfStasisConnections Nombre de connexions en attente de l'achèvement d'une action et par conséquent non disponibles pour une utilisation par votre application.
SoftConnectsPerSecond Nombre de connexions actives extraites du pool de connexions. Note: Ce compteur de performances n’est pas activé par défaut. Pour activer ce compteur de performance, voir Activation des compteurs désactivés par défaut.
SoftDisconnectsPerSecond Nombre de connexions actives retournées au regroupement de connexions. Note: Ce compteur de performances n’est pas activé par défaut. Pour activer ce compteur de performance, voir Activation des compteurs désactivés par défaut.

Activer les compteurs désactivés par défaut

Les compteurs de performance NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond et SoftConnectsPerSecond sont désactivés par défaut. Ajoutez les informations suivantes dans le fichier de configuration de l'application pour les activer :

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

Récupérer les valeurs des compteurs de performances

L'application console suivante montre comment récupérer les valeurs de compteur de performance dans votre application. Les connexions doivent être ouvertes et actives pour que les informations soient retournées pour l’ensemble des compteurs de performances du fournisseur de données Microsoft SqlClient pour SQL Server.

Note

Cet exemple utilise la base de données d’exemple AdventureWorks. Les chaînes de connexion fournies dans l’exemple de code supposent que la base de données est installée et disponible sur l’ordinateur local, et que vous avez créé des connexions qui correspondent à celles fournies dans les chaînes de connexion. Vous devrez peut-être activer les connexions SQL Server si votre serveur est configuré à l’aide des paramètres de sécurité par défaut qui autorisent uniquement l’authentification Windows. Modifiez les chaînes de connexion en fonction de votre environnement.

Exemple

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

namespace SqlClient_PerformanceCounter
{
    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>;";
        }
    }
}