Delen via


Prestatiemeteritems in ADO.NET

ADO.NET 2.0 heeft uitgebreide ondersteuning geïntroduceerd voor prestatiemeteritems die ondersteuning voor zowel System.Data.SqlClientSystem.Data.OracleClientals . De System.Data.SqlClient prestatiemeteritems die beschikbaar zijn in eerdere versies van ADO.NET zijn afgeschaft en vervangen door de nieuwe prestatiemeteritems die in dit onderwerp worden besproken. U kunt ADO.NET prestatiemeteritems gebruiken om de status van uw toepassing en de verbindingsbronnen die worden gebruikt te bewaken. Prestatiemeteritems kunnen worden bewaakt met Behulp van Windows Performance Monitor of kunnen programmatisch worden geopend met behulp van de PerformanceCounter klasse in de System.Diagnostics naamruimte.

Beschikbare prestatiemeteritems

Er zijn momenteel 14 verschillende prestatiemeteritems beschikbaar voor System.Data.SqlClient en System.Data.OracleClient zoals beschreven in de volgende tabel. Houd er rekening mee dat de namen voor de afzonderlijke tellers niet zijn gelokaliseerd in regionale versies van Microsoft .NET Framework.

Prestatiemeteritem Beschrijving
HardConnectsPerSecond Het aantal verbindingen per seconde dat wordt gemaakt op een databaseserver.
HardDisconnectsPerSecond Het aantal verbroken verbindingen per seconde dat wordt uitgevoerd op een databaseserver.
NumberOfActiveConnectionPoolGroups Het aantal unieke verbindingsgroepgroepen dat actief is. Deze teller wordt bepaald door het aantal unieke verbindingsreeks s die in het AppDomain worden gevonden.
NumberOfActiveConnectionPools Het totale aantal verbindingsgroepen.
NumberOfActiveConnections Het aantal actieve verbindingen dat momenteel wordt gebruikt. Opmerking: deze prestatiemeteritem is niet standaard ingeschakeld. Zie Standaardtellers activeren om dit prestatiemeteritem in te schakelen.
NumberOfFreeConnections Het aantal verbindingen dat beschikbaar is voor gebruik in de verbindingsgroepen. Opmerking: deze prestatiemeteritem is niet standaard ingeschakeld. Zie Standaardtellers activeren om dit prestatiemeteritem in te schakelen.
NumberOfInactiveConnectionPoolGroups Het aantal unieke verbindingsgroepgroepen dat is gemarkeerd voor het verwijderen. Deze teller wordt bepaald door het aantal unieke verbindingsreeks s die in het AppDomain worden gevonden.
NumberOfInactiveConnectionPools Het aantal inactieve verbindingsgroepen dat geen recente activiteit heeft gehad en die wachten om te worden verwijderd.
NumberOfNonPooledConnections Het aantal actieve verbindingen dat niet is gegroepeerd.
NumberOfPooledConnections Het aantal actieve verbindingen dat wordt beheerd door de infrastructuur voor groepsgewijze verbindingen.
NumberOfReclaimedConnections Het aantal verbindingen dat is vrijgemaakt via garbagecollection waar Close of Dispose niet door de toepassing is aangeroepen. Het sluiten of verwijderen van verbindingen doet de prestaties niet expliciet pijn.
NumberOfStasisConnections Het aantal verbindingen dat momenteel wacht op voltooiing van een actie en die daarom niet beschikbaar is voor gebruik door uw toepassing.
SoftConnectsPerSecond Het aantal actieve verbindingen dat wordt opgehaald uit de verbindingsgroep. Opmerking: deze prestatiemeteritem is niet standaard ingeschakeld. Zie Standaardtellers activeren om dit prestatiemeteritem in te schakelen.
SoftDisconnectsPerSecond Het aantal actieve verbindingen dat wordt geretourneerd naar de verbindingsgroep. Opmerking: deze prestatiemeteritem is niet standaard ingeschakeld. Zie Standaardtellers activeren om dit prestatiemeteritem in te schakelen.

Verbinding maken iongroepgroepen en Verbinding maken ionpools

Wanneer u Windows-verificatie (geïntegreerde beveiliging) gebruikt, moet u zowel de prestatiemeteritems als de NumberOfActiveConnectionPoolGroupsNumberOfActiveConnectionPools prestatiemeteritems bewaken. De reden hiervoor is dat verbindingsgroepgroepen zijn toegewezen aan unieke verbindingsreeks s. Wanneer geïntegreerde beveiliging wordt gebruikt, worden verbindingsgroepen toegewezen aan verbindingsreeks s en worden er bovendien afzonderlijke pools voor afzonderlijke Windows-identiteiten gemaakt. Als Fred en Julie bijvoorbeeld elk binnen hetzelfde AppDomain de verbindingsreeks "Data Source=MySqlServer;Integrated Security=true"gebruiken, wordt er een verbindingsgroep gemaakt voor de verbindingsreeks en worden er twee extra pools gemaakt, één voor Fred en één voor Julie. Als John en Martha een verbindingsreeks met een identieke SQL Server-aanmelding gebruiken, "Data Source=MySqlServer;User Id=lowPrivUser;Password=[PLACEHOLDER]"wordt er slechts één pool gemaakt voor de lowPrivUser-identiteit.

Standaardtellers activeren

De prestatiemeteritemsNumberOfFreeConnections, NumberOfActiveConnectionsen SoftDisconnectsPerSecondSoftConnectsPerSecond zijn standaard uitgeschakeld. Voeg de volgende informatie toe aan het configuratiebestand van de toepassing om ze in te schakelen:

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

Waarden voor prestatiemeteritems ophalen

In de volgende consoletoepassing ziet u hoe u prestatiemeteritems ophaalt in uw toepassing. Verbinding maken ionen moeten open en actief zijn om informatie te retourneren voor alle ADO.NET prestatiemeteritems.

Notitie

In dit voorbeeld wordt de voorbeelddatabase AdventureWorks gebruikt die is opgenomen in SQL Server. Bij de verbindingsreeks in de voorbeeldcode wordt ervan uitgegaan dat de database is geïnstalleerd en beschikbaar is op de lokale computer met een exemplaarnaam van SqlExpress en dat u SQL Server-aanmeldingen hebt gemaakt die overeenkomen met de aanmeldingen die zijn opgegeven in de verbindingsreeks s. Mogelijk moet u SQL Server-aanmeldingen inschakelen als uw server is geconfigureerd met behulp van de standaardbeveiligingsinstellingen die alleen Windows-verificatie toestaan. Pas de verbindingsreeks indien nodig aan uw omgeving aan.

Voorbeeld

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

Zie ook