Condividi tramite


Contatori delle prestazioni in SqlClient

Si applica a: .NET Framework Non supportato. .NET Core Non supportato. .NET Standard

Scarica ADO.NET

È possibile usare i contatori delle prestazioni Microsoft.Data.SqlClient per monitorare lo stato dell'applicazione e le risorse di connessione usate. I contatori delle prestazioni possono essere monitorati tramite Performance Monitor di Windows. In alternativa, è possibile accedervi a livello di codice usando la classe PerformanceCounter nello spazio dei nomi System.Diagnostics.

Contatori delle prestazioni disponibili

Attualmente sono disponibili 14 diversi contatori delle prestazioni per Microsoft.Data.SqlClient come descritto nella tabella seguente.

Contatore delle prestazioni Descrizione
HardConnectsPerSecond Numero di connessioni al secondo eseguite a un server database.
HardDisconnectsPerSecond Numero di disconnessioni al secondo eseguite a un server database.
NumberOfActiveConnectionPoolGroups Numero di gruppi univoci di pool di connessioni attivi. Questo contatore è controllato dal numero di stringhe di connessione univoche disponibili in AppDomain.
NumberOfActiveConnectionPools Numero complessivo di pool di connessioni.
NumberOfActiveConnections Numero di connessioni attive al momento in uso. Nota: Per impostazione predefinita, questo contatore delle prestazioni non è abilitato. Per abilitarlo, consultare Activate off-by-default counters (Attivare i contatori disattivati per impostazione predefinita).
NumberOfFreeConnections Numero di connessioni disponibili per l'uso nei pool di connessioni. Nota: Per impostazione predefinita, questo contatore delle prestazioni non è abilitato. Per abilitarlo, consultare Activate off-by-default counters (Attivare i contatori disattivati per impostazione predefinita).
NumberOfInactiveConnectionPoolGroups Numero di gruppi univoci di pool di connessioni attivi contrassegnati per l'eliminazione. Questo contatore è controllato dal numero di stringhe di connessione univoche disponibili in AppDomain.
NumberOfInactiveConnectionPools Numero di pool di connessioni inattivi in cui non si è verificata alcuna attività recente e che sono in attesa di essere eliminati.
NumberOfNonPooledConnections Numero di connessioni attive che non sono in pool.
NumberOfPooledConnections Numero di connessioni attive gestite dall'infrastruttura del pool di connessioni.
NumberOfReclaimedConnections Numero di connessioni che sono state recuperate tramite Garbage Collection laddove per l'applicazione non è stato chiamato Close o Dispose. Nota La chiusura o l'eliminazione non esplicita delle connessioni danneggia le prestazioni.
NumberOfStasisConnections Numero di connessioni attualmente in attesa del completamento di un'azione e che non sono pertanto disponibili per l'uso da parte dell'applicazione.
SoftConnectsPerSecond Numero di connessioni attive rimosse dal pool di connessioni. Nota: Per impostazione predefinita, questo contatore delle prestazioni non è abilitato. Per abilitarlo, consultare Activate off-by-default counters (Attivare i contatori disattivati per impostazione predefinita).
SoftDisconnectsPerSecond Numero di connessioni attive restituite al pool di connessioni. Nota: Per impostazione predefinita, questo contatore delle prestazioni non è abilitato. Per abilitarlo, consultare Activate off-by-default counters (Attivare i contatori disattivati per impostazione predefinita).

Attivare i contatori disattivati per impostazione predefinita

I contatori delle prestazioni NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond e SoftConnectsPerSecond sono disattivati per impostazione predefinita. Aggiungere le informazioni seguenti al file di configurazione dell'applicazione per abilitarli:

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

Recuperare i valori del contatore delle prestazioni

Nell'applicazione console seguente viene illustrato come recuperare i valori dei contatori delle prestazioni nell'applicazione. Per la restituzione delle informazioni per tutti i provider di dati Microsoft SqlClient per i contatori delle prestazioni di SQL Server, è necessario che le connessioni siano aperte e attive.

Nota

In questo esempio viene usato il database campione AdventureWorks. Le stringhe di connessione fornite nel codice di esempio presuppongono che il database sia installato e disponibile nel computer locale e che siano stati creati account di accesso corrispondenti a quelli specificati nelle stringhe di connessione. Può essere necessario abilitare gli account di accesso di SQL Server se il server è stato configurato con le impostazioni di sicurezza predefinite, che consentono solo l'autenticazione di Windows. Apportare le modifiche necessarie alle stringhe di connessione in base all'ambiente.

Esempio

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

Vedi anche