Čítače výkonu v ADO.NET

ADO.NET 2.0 zavedla rozšířenou podporu čítačů výkonu, které zahrnují podporu obou System.Data.SqlClient a System.Data.OracleClient. System.Data.SqlClient Čítače výkonu dostupné v předchozích verzích ADO.NET byly zastaralé a nahrazeny čítači výkonu novými čítači výkonu popsanými v tomto tématu. Pomocí ADO.NET čítačů výkonu můžete monitorovat stav aplikace a prostředky připojení, které používá. Čítače výkonu lze monitorovat pomocí systému Windows Sledování výkonu nebo k němu lze přistupovat prostřednictvím kódu programu pomocí PerformanceCounter třídy v System.Diagnostics oboru názvů.

Dostupné čítače výkonu

V současné době je k dispozici System.Data.SqlClient 14 různých čítačů výkonu, System.Data.OracleClient jak je popsáno v následující tabulce. Všimněte si, že názvy jednotlivých čítačů nejsou lokalizovány napříč regionálními verzemi rozhraní Microsoft .NET Framework.

Čítač výkonu Popis
HardConnectsPerSecond Počet připojení za sekundu, která se provádí na databázovém serveru.
HardDisconnectsPerSecond Počet odpojení za sekundu, které se provádí na databázovém serveru.
NumberOfActiveConnectionPoolGroups Počet aktivních skupin fondu připojení. Tento čítač je řízen počtem jedinečných připojovací řetězec nalezených v doméně AppDomain.
NumberOfActiveConnectionPools Celkový počet fondů připojení.
NumberOfActiveConnections Počet aktivních připojení, která se aktuálně používají. Poznámka: Tento čítač výkonu není ve výchozím nastavení povolen. Pokud chcete povolit tento čítač výkonu, přečtěte si téma Aktivace čítačů mimo výchozí nastavení.
NumberOfFreeConnections Počet připojení, která jsou k dispozici pro použití ve fondech připojení. Poznámka: Tento čítač výkonu není ve výchozím nastavení povolen. Pokud chcete povolit tento čítač výkonu, přečtěte si téma Aktivace čítačů mimo výchozí nastavení.
NumberOfInactiveConnectionPoolGroups Počet jedinečných skupin fondu připojení, které jsou označené k vyřazení. Tento čítač je řízen počtem jedinečných připojovací řetězec nalezených v doméně AppDomain.
NumberOfInactiveConnectionPools Počet neaktivních fondů připojení, které nemají žádnou nedávnou aktivitu, a čekají na odstranění.
NumberOfNonPooledConnections Početaktivních
NumberOfPooledConnections Počet aktivních připojení spravovaných infrastrukturou sdružování připojení.
NumberOfReclaimedConnections Počet připojení, která byla uvolněna prostřednictvím uvolňování paměti, kde Close nebo Dispose nebyla volána aplikací. Nezavírání nebo zakázání připojení snižuje výkon.
NumberOfStasisConnections Počet připojení, která aktuálně čekají na dokončení akce a které jsou proto nedostupné pro použití vaší aplikací.
SoftConnectsPerSecond Počet aktivních připojení, která se načítají z fondu připojení. Poznámka: Tento čítač výkonu není ve výchozím nastavení povolen. Pokud chcete povolit tento čítač výkonu, přečtěte si téma Aktivace čítačů mimo výchozí nastavení.
SoftDisconnectsPerSecond Počet aktivních připojení, která se vrací do fondu připojení. Poznámka: Tento čítač výkonu není ve výchozím nastavení povolen. Pokud chcete povolit tento čítač výkonu, přečtěte si téma Aktivace čítačů mimo výchozí nastavení.

Skupiny fondů Připojení ion a fondy Připojení ion

Při použití ověřování systému Windows (integrovaného zabezpečení) je nutné monitorovat čítače výkonu NumberOfActiveConnectionPoolGroups i NumberOfActiveConnectionPools čítače výkonu. Důvodem je, že skupiny fondu připojení se mapují na jedinečné připojovací řetězec. Při použití integrovaného zabezpečení se fondy připojení mapují na připojovací řetězec a navíc vytvářejí samostatné fondy pro jednotlivé identity Systému Windows. Pokud například Fred a Julie, každý ve stejné AppDomain, oba používají připojovací řetězec "Data Source=MySqlServer;Integrated Security=true", vytvoří se skupina fondu připojení pro připojovací řetězec a vytvoří se dva další fondy, jeden pro Fred a jeden pro Julie. Pokud Jan a Martha používají připojovací řetězec se stejným přihlášením k SQL Serveru, "Data Source=MySqlServer;User Id=lowPrivUser;Password=[PLACEHOLDER]"vytvoří se pro identitu lowPrivUser pouze jeden fond.

Aktivace čítačů mimo výchozí nastavení

Čítače výkonu NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSeconda SoftConnectsPerSecond jsou ve výchozím nastavení vypnuté. Přidejte do konfiguračního souboru aplikace následující informace, abyste je povolili:

<system.diagnostics>
  <switches>
    <add name="ConnectionPoolPerformanceCounterDetail"
         value="4"/>
  </switches>
</system.diagnostics>

Načítání hodnot čítačů výkonu

Následující konzolová aplikace ukazuje, jak v aplikaci načíst hodnoty čítače výkonu. Připojení hodnoty musí být otevřené a aktivní, aby se informace vrátily pro všechny čítače výkonu ADO.NET.

Poznámka:

Tento příklad používá ukázkovou databázi AdventureWorks , která je součástí SQL Serveru. Připojovací řetězec zadané v ukázkovém kódu předpokládají, že je databáze nainstalovaná a dostupná v místním počítači s názvem instance SqlExpress a že jste vytvořili přihlášení SQL Serveru, která odpovídají těm, které jsou součástí připojovací řetězec. Pokud je váš server nakonfigurovaný pomocí výchozího nastavení zabezpečení, které povolují pouze ověřování systému Windows, možná budete muset povolit přihlášení k SQL Serveru. Podle potřeby upravte připojovací řetězec tak, aby vyhovovaly vašemu prostředí.

Příklad

Option Explicit On
Option Strict On

Imports System.Data.SqlClient
Imports System.Diagnostics
Imports System.Runtime.InteropServices

Class Program

    Private PerfCounters(9) As PerformanceCounter
    Private connection As SqlConnection = New SqlConnection

    Public Shared Sub Main()
        Dim prog As Program = 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()
    End Sub

    Private Sub CreateConnections()
        ' List the Performance counters.
        WritePerformanceCounters()

        ' Create 4 connections and display counter information.
        Dim connection1 As SqlConnection = New SqlConnection( _
           GetIntegratedSecurityConnectionString)
        connection1.Open()
        Console.WriteLine("Opened the 1st Connection:")
        WritePerformanceCounters()

        Dim connection2 As SqlConnection = New SqlConnection( _
           GetSqlConnectionStringDifferent)
        connection2.Open()
        Console.WriteLine("Opened the 2nd Connection:")
        WritePerformanceCounters()

        Console.WriteLine("Opened the 3rd Connection:")
        Dim connection3 As SqlConnection = New SqlConnection( _
           GetSqlConnectionString)
        connection3.Open()
        WritePerformanceCounters()

        Dim connection4 As SqlConnection = 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()
    End Sub

    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
    End Enum

    Private Sub SetUpPerformanceCounters()
        connection.Close()
        Me.PerfCounters(9) = New PerformanceCounter()

        Dim instanceName As String = GetInstanceName()
        Dim apc As Type = GetType(ADO_Net_Performance_Counters)
        Dim i As Integer = 0
        Dim s As String = ""
        For Each s In [Enum].GetNames(apc)
            Me.PerfCounters(i) = New PerformanceCounter()
            Me.PerfCounters(i).CategoryName = ".NET Data Provider for SqlServer"
            Me.PerfCounters(i).CounterName = s
            Me.PerfCounters(i).InstanceName = instanceName
            i = (i + 1)
        Next
    End Sub

    Private Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Integer

    Private Function GetInstanceName() As String
        'This works for Winforms apps.
        Dim instanceName As String = _
           System.Reflection.Assembly.GetEntryAssembly.GetName.Name

        ' Must replace special characters like (, ), #, /, \\
        Dim instanceName2 As String = _
           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("\\", "_")

        Dim pid As String = GetCurrentProcessId.ToString
        instanceName = (instanceName + ("[" & (pid & "]")))
        Console.WriteLine("Instance Name: {0}", instanceName)
        Console.WriteLine("---------------------------")
        Return instanceName
    End Function

    Private Sub WritePerformanceCounters()
        Console.WriteLine("---------------------------")
        For Each p As PerformanceCounter In Me.PerfCounters
            Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue)
        Next
        Console.WriteLine("---------------------------")
    End Sub

    Private Shared Function GetIntegratedSecurityConnectionString() As String
        ' To avoid storing the connection string in your code,
        ' you can retrieve it from a configuration file.
        Return ("Data Source=.\SqlExpress;Integrated Security=True;" &
          "Initial Catalog=AdventureWorks")
    End Function

    Private Shared Function GetSqlConnectionString() As String
        ' To avoid storing the connection string in your code,
        ' you can retrieve it from a configuration file.
        Return ("Data Source=.\SqlExpress;User Id=LowPriv;Password=[PLACEHOLDER];" &
          "Initial Catalog=AdventureWorks")
    End Function

    Private Shared Function GetSqlConnectionStringDifferent() As String
        ' To avoid storing the connection string in your code,
        ' you can retrieve it from a configuration file.
        Return ("Initial Catalog=AdventureWorks;Data Source=.\SqlExpress;" & _
          "User Id=LowPriv;Password=[PLACEHOLDER];")
    End Function
End Class
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Runtime.InteropServices;

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=.\SqlExpress;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=.\SqlExpress;User Id=LowPriv;Password=[PLACEHOLDER];" +
          "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=.\SqlExpress;" +
          "User Id=LowPriv;Password=[PLACEHOLDER];";
    }
}

Viz také