Prestatiemeteritems in ADO.NET
ADO.NET 2.0 heeft uitgebreide ondersteuning geïntroduceerd voor prestatiemeteritems die ondersteuning voor zowel System.Data.SqlClient System.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. |
Groepen en verbindingsgroepen voor verbindingsgroepen
Wanneer u Windows-verificatie (geïntegreerde beveiliging) gebruikt, moet u zowel de prestatiemeteritems als de NumberOfActiveConnectionPoolGroups
NumberOfActiveConnectionPools
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.
Belangrijk
Microsoft raadt u aan de veiligste verificatiestroom te gebruiken die beschikbaar is. Als u verbinding maakt met Azure SQL, is Managed Identities voor Azure-resources de aanbevolen verificatiemethode.
Standaardtellers activeren
De prestatiemeteritemsNumberOfFreeConnections
, NumberOfActiveConnections
en SoftDisconnectsPerSecond
SoftConnectsPerSecond
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. Verbindingen moeten geopend en actief zijn om gegevens te kunnen 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
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("---------------------------");
}
}