Partilhar via


Contadores de desempenho no SqlClient

Aplica-se a: .NET Framework

Baixar ADO.NET

Pode usar Microsoft.Data.SqlClient contadores de desempenho para monitorizar o estado da sua aplicação e os recursos de ligação que utiliza. Os contadores de desempenho podem ser monitorados usando o PerformanceCounter Monitor de Desempenho do Windows ou podem ser acessados programaticamente usando a System.Diagnostics classe no namespace.

Importante

A abordagem baseada em PerformanceCounter, descrita neste artigo, requer .NET Framework e funciona apenas em Windows. A System.Diagnostics.PerformanceCounter classe não está disponível em plataformas .NET Core, .NET 5+ ou não Windows. Para monitorização multiplataforma em aplicações .NET modernas, utilize contadores de eventos em SqlClient .

Contadores de desempenho disponíveis

Atualmente, existem 14 contadores de desempenho diferentes disponíveis para Microsoft.Data.SqlClient , conforme descrito na tabela seguinte.

Contador de desempenho Description
HardConnectsPerSecond O número de conexões por segundo que estão sendo feitas a um servidor de banco de dados.
HardDisconnectsPerSecond O número de desconexões por segundo que estão sendo feitas em um servidor de banco de dados.
NumberOfActiveConnectionPoolGroups O número de grupos de pool de conexões exclusivos que estão ativos. Esse contador é controlado pelo número de cadeias de conexão exclusivas encontradas no AppDomain.
NumberOfActiveConnectionPools O número total de pools de conexões.
NumberOfActiveConnections O número de conexões ativas que estão atualmente em uso. Nota: Este contador de desempenho não está ativado por defeito. Para ativar este contador de desempenho, veja Ativar contadores desligados por defeito.
NumberOfFreeConnections O número de conexões disponíveis para uso nos pools de conexões. Nota: Este contador de desempenho não está ativado por defeito. Para ativar este contador de desempenho, veja Ativar contadores desligados por defeito.
NumberOfInactiveConnectionPoolGroups O número de grupos de conexões exclusivos marcados para remoção. Esse contador é controlado pelo número de cadeias de conexão exclusivas encontradas no AppDomain.
NumberOfInactiveConnectionPools O número de pools de ligação inativos que não tiveram atividade recente e estão à espera de serem eliminados.
NumberOfNonPooledConnections O número de conexões ativas que não são agrupadas.
NumberOfPooledConnections O número de conexões ativas que estão sendo gerenciadas pela infraestrutura do pool de conexões.
NumberOfReclaimedConnections O número de ligações que foram recuperadas através da recolha de lixo porque a aplicação não chamou Close ou Dispose. Observação Não fechar ou descartar conexões explicitamente prejudica o desempenho.
NumberOfStasisConnections O número de conexões atualmente aguardando a conclusão de uma ação e que, portanto, não estão disponíveis para uso pelo seu aplicativo.
SoftConnectsPerSecond O número de conexões ativas que estão sendo extraídas do pool de conexões. Nota: Este contador de desempenho não está ativado por defeito. Para ativar este contador de desempenho, veja Ativar contadores desligados por defeito.
SoftDisconnectsPerSecond O número de conexões ativas que estão sendo retornadas ao pool de conexões. Nota: Este contador de desempenho não está ativado por defeito. Para ativar este contador de desempenho, veja Ativar contadores desligados por defeito.

Ativar contadores desligados por defeito

Os contadores de desempenho NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond e SoftConnectsPerSecond estão desativados por padrão. Adicione as seguintes informações ao arquivo de configuração do aplicativo para habilitá-los:

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

Recuperar valores de contadores de desempenho

O aplicativo de console a seguir mostra como recuperar valores de contador de desempenho em seu aplicativo. As ligações devem estar abertas e ativas para que a informação seja devolvida a todos os contadores de desempenho do Microsoft SqlClient Data Provider for SQL Server.

Observação

Este exemplo utiliza a base de dados de exemplo AdventureWorks. As cadeias de ligação fornecidas no código de exemplo assumem que a base de dados está instalada e disponível no computador local, e que criou logins que correspondem aos fornecidos nas cadeias de ligação. Pode ser necessário ativar os logins do SQL Server se o seu servidor estiver configurado usando as definições de segurança predefinidas, que permitem apenas a autenticação do Windows. Modifique as cadeias de conexão conforme necessário para se adequar ao seu ambiente.

Example

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>;";
        }
    }
}