Megosztás a következőn keresztül:


Teljesítményszámlálók a ADO.NET

ADO.NET 2.0 kiterjesztett támogatást vezetett be a teljesítményszámlálókhoz, amelyek egyaránt System.Data.SqlClient és System.Data.OracleClient. A System.Data.SqlClient ADO.NET korábbi verzióiban elérhető teljesítményszámlálók elavultak, és a jelen témakörben tárgyalt új teljesítményszámlálókra lettek cserélve. A ADO.NET teljesítményszámlálókkal figyelheti az alkalmazás állapotát és az általa használt kapcsolati erőforrásokat. A teljesítményszámlálók a Windows Teljesítményfigyelővel monitorozhatók, vagy programozott módon érhetők el a PerformanceCounterSystem.Diagnostics névtérben lévő osztály használatával.

Elérhető teljesítményszámlálók

Jelenleg 14 különböző teljesítményszámláló érhető el az System.Data.SqlClientSystem.Data.OracleClient alábbi táblázatban leírtak szerint. Vegye figyelembe, hogy az egyes számlálók neve nem honosított a Microsoft .NET-keretrendszer regionális verzióiban.

Teljesítményszámláló Leírás
HardConnectsPerSecond Az adatbázis-kiszolgálóval létesített kapcsolatok másodpercenkénti száma.
HardDisconnectsPerSecond Az adatbázis-kiszolgálóra jutó leválasztások másodpercenkénti száma.
NumberOfActiveConnectionPoolGroups Az aktív egyedi kapcsolatkészlet-csoportok száma. Ezt a számlálót az AppDomainben található egyedi kapcsolati sztring száma vezérli.
NumberOfActiveConnectionPools A kapcsolatkészletek teljes száma.
NumberOfActiveConnections A jelenleg használatban lévő aktív kapcsolatok száma. Megjegyzés: Ez a teljesítményszámláló alapértelmezés szerint nincs engedélyezve. Ennek a teljesítményszámlálónak az engedélyezéséhez tekintse meg az alapértelmezett számlálók aktiválását.
NumberOfFreeConnections A kapcsolatkészletekben használható kapcsolatok száma. Megjegyzés: Ez a teljesítményszámláló alapértelmezés szerint nincs engedélyezve. Ennek a teljesítményszámlálónak az engedélyezéséhez tekintse meg az alapértelmezett számlálók aktiválását.
NumberOfInactiveConnectionPoolGroups A metszésre megjelölt egyedi kapcsolatkészlet-csoportok száma. Ezt a számlálót az AppDomainben található egyedi kapcsolati sztring száma vezérli.
NumberOfInactiveConnectionPools Azon inaktív kapcsolatkészletek száma, amelyek nem rendelkeznek legutóbbi tevékenységekkel, és amelyek az ártalmatlanításra várnak.
NumberOfNonPooledConnections A nem készletezett aktív kapcsolatok száma.
NumberOfPooledConnections A kapcsolatkészletezési infrastruktúra által felügyelt aktív kapcsolatok száma.
NumberOfReclaimedConnections Azoknak a kapcsolatoknak a száma, amelyeket a szemétgyűjtés során visszanyertek, ahol Close az alkalmazás meghívta vagy Dispose nem. A kapcsolatok explicit bezárása vagy megszüntetése nem rontja a teljesítményt.
NumberOfStasisConnections Azoknak a kapcsolatoknak a száma, amelyek jelenleg egy művelet befejezésére várnak, és ezért nem használhatók az alkalmazás számára.
SoftConnectsPerSecond A kapcsolatkészletből lekért aktív kapcsolatok száma. Megjegyzés: Ez a teljesítményszámláló alapértelmezés szerint nincs engedélyezve. Ennek a teljesítményszámlálónak az engedélyezéséhez tekintse meg az alapértelmezett számlálók aktiválását.
SoftDisconnectsPerSecond A kapcsolatkészletbe visszaküldött aktív kapcsolatok száma. Megjegyzés: Ez a teljesítményszámláló alapértelmezés szerint nincs engedélyezve. Ennek a teljesítményszámlálónak az engedélyezéséhez tekintse meg az alapértelmezett számlálók aktiválását.

Csatlakozás ion-készletcsoportok és Csatlakozás ion-készletek

A Windows-hitelesítés (integrált biztonság) használatakor a teljesítményszámlálókat és NumberOfActiveConnectionPools a NumberOfActiveConnectionPoolGroups teljesítményszámlálókat is figyelnie kell. Ennek az az oka, hogy a kapcsolatkészletcsoportok egyedi kapcsolati sztring képeznek le. Az integrált biztonság használatakor a kapcsolatkészletek kapcsolati sztring képeznek le, és külön készleteket hozhatnak létre az egyes Windows-identitásokhoz. Ha például Fred és Julie ugyanabban az AppDomainben használják a kapcsolati sztring"Data Source=MySqlServer;Integrated Security=true", létrejön egy kapcsolatkészlet-csoport a kapcsolati sztring, és két további készlet jön létre, egyet Frednek, egyet Pedig Julie-nak. Ha John és Martha azonos SQL Server-bejelentkezéssel rendelkező kapcsolati sztring használnak, "Data Source=MySqlServer;User Id=lowPrivUser;Password=[PLACEHOLDER]"akkor a rendszer csak egyetlen készletet hoz létre az alacsonyPrivUser-identitáshoz.

Alapértelmezés szerinti számlálók aktiválása

A teljesítményszámlálók NumberOfFreeConnectionsNumberOfActiveConnections, és SoftDisconnectsPerSecondSoftConnectsPerSecond alapértelmezés szerint ki vannak kapcsolva. Adja hozzá az alábbi információkat az alkalmazás konfigurációs fájljába az engedélyezésükhöz:

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

Teljesítményszámláló értékeinek beolvasása

Az alábbi konzolalkalmazás bemutatja, hogyan kérhetők le teljesítményszámláló értékek az alkalmazásban. Csatlakozás a ADO.NET teljesítményszámlálók adatainak visszaadásához nyitottnak és aktívnak kell lennie.

Feljegyzés

Ez a példa az SQL Serverhez mellékelt AdventureWorks-mintaadatbázist használja. A mintakódban megadott kapcsolati sztring feltételezik, hogy az adatbázis telepítve van és elérhető a helyi számítógépen az SqlExpress példánynevével, és hogy olyan SQL Server-bejelentkezéseket hozott létre, amelyek megfelelnek a kapcsolati sztring-ben megadottaknak. Előfordulhat, hogy engedélyeznie kell az SQL Server-bejelentkezéseket, ha a kiszolgáló az alapértelmezett biztonsági beállításokkal van konfigurálva, amelyek csak a Windows-hitelesítést teszik lehetővé. Szükség szerint módosítsa a kapcsolati sztring a környezetének megfelelően.

Példa

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

Lásd még