Prestandaräknare i ADO.NET
ADO.NET 2.0 introducerade utökat stöd för prestandaräknare som innehåller stöd för både System.Data.SqlClient och System.Data.OracleClient. Prestandaräknarna System.Data.SqlClient som är tillgängliga i tidigare versioner av ADO.NET har blivit inaktuella och ersatta med de nya prestandaräknarna som beskrivs i det här avsnittet. Du kan använda ADO.NET prestandaräknare för att övervaka status för ditt program och de anslutningsresurser som används. Prestandaräknare kan övervakas med hjälp av Windows Prestandaövervakare eller kan nås programmatiskt med hjälp av PerformanceCounter klassen i System.Diagnostics namnområdet.
Tillgängliga prestandaräknare
För närvarande finns det 14 olika prestandaräknare tillgängliga för System.Data.SqlClient och System.Data.OracleClient enligt beskrivningen i följande tabell. Observera att namnen för de enskilda räknarna inte är lokaliserade i regionala versioner av Microsoft .NET Framework.
Prestandaräknare | beskrivning |
---|---|
HardConnectsPerSecond |
Antalet anslutningar per sekund som görs till en databasserver. |
HardDisconnectsPerSecond |
Antalet frånkopplingar per sekund som görs till en databasserver. |
NumberOfActiveConnectionPoolGroups |
Antalet unika anslutningspoolgrupper som är aktiva. Den här räknaren styrs av antalet unika niska veze som finns i AppDomain. |
NumberOfActiveConnectionPools |
Det totala antalet anslutningspooler. |
NumberOfActiveConnections |
Antalet aktiva anslutningar som används för närvarande. Obs! Den här prestandaräknaren är inte aktiverad som standard. Information om hur du aktiverar den här prestandaräknaren finns i Aktivera off-by-default-räknare. |
NumberOfFreeConnections |
Antalet anslutningar som är tillgängliga för användning i anslutningspoolerna. Obs! Den här prestandaräknaren är inte aktiverad som standard. Information om hur du aktiverar den här prestandaräknaren finns i Aktivera off-by-default-räknare. |
NumberOfInactiveConnectionPoolGroups |
Antalet unika anslutningspoolgrupper som har markerats för rensning. Den här räknaren styrs av antalet unika niska veze som finns i AppDomain. |
NumberOfInactiveConnectionPools |
Antalet inaktiva anslutningspooler som inte har haft någon nyligen genomförd aktivitet och som väntar på att tas bort. |
NumberOfNonPooledConnections |
Antalet aktiva anslutningar som inte är poolade. |
NumberOfPooledConnections |
Antalet aktiva anslutningar som hanteras av infrastrukturen för anslutningspooler. |
NumberOfReclaimedConnections |
Antalet anslutningar som har återtagits via skräpinsamling där Close programmet anropade eller Dispose inte anropades. Att inte uttryckligen stänga eller ta bort anslutningar skadar prestandan. |
NumberOfStasisConnections |
Antalet anslutningar som väntar på att slutföra en åtgärd och som därför inte är tillgängliga för användning av ditt program. |
SoftConnectsPerSecond |
Antalet aktiva anslutningar som hämtas från anslutningspoolen. Obs! Den här prestandaräknaren är inte aktiverad som standard. Information om hur du aktiverar den här prestandaräknaren finns i Aktivera off-by-default-räknare. |
SoftDisconnectsPerSecond |
Antalet aktiva anslutningar som returneras till anslutningspoolen. Obs! Den här prestandaräknaren är inte aktiverad som standard. Information om hur du aktiverar den här prestandaräknaren finns i Aktivera off-by-default-räknare. |
Anslutningspoolgrupper och anslutningspooler
När du använder Windows-autentisering (integrerad säkerhet) måste du övervaka både NumberOfActiveConnectionPoolGroups
prestandaräknarna och NumberOfActiveConnectionPools
. Orsaken är att anslutningspoolgrupper mappas till unika niska veze. När integrerad säkerhet används mappas anslutningspooler till niska veze och skapar dessutom separata pooler för enskilda Windows-identiteter. Om Till exempel Fred och Julie, var och en inom samma AppDomain, båda använder niska veze "Data Source=MySqlServer;Integrated Security=true"
, skapas en anslutningspoolgrupp för niska veze och ytterligare två pooler skapas, en för Fred och en för Julie. Om John och Martha använder en niska veze med en identisk SQL Server-inloggning "Data Source=MySqlServer;User Id=lowPrivUser;Password=[PLACEHOLDER]"
skapas bara en enda pool för lowPrivUser-identiteten.
Viktigt!
Microsoft rekommenderar att du använder det säkraste tillgängliga autentiseringsflödet. Om du ansluter till Azure SQL är hanterade identiteter för Azure-resurser den rekommenderade autentiseringsmetoden.
Aktivera off-by-default-räknare
Prestandaräknarna NumberOfFreeConnections
, NumberOfActiveConnections
, SoftDisconnectsPerSecond
och SoftConnectsPerSecond
är inaktiverade som standard. Lägg till följande information i programmets konfigurationsfil för att aktivera dem:
<system.diagnostics>
<switches>
<add name="ConnectionPoolPerformanceCounterDetail"
value="4"/>
</switches>
</system.diagnostics>
Hämtar värden för prestandaräknare
Följande konsolprogram visar hur du hämtar prestandaräknarens värden i ditt program. Anslutningar måste vara öppna och aktiva för att information ska returneras för alla ADO.NET prestandaräknare.
Kommentar
I det här exemplet används exempeldatabasen AdventureWorks som ingår i SQL Server. De niska veze som anges i exempelkoden förutsätter att databasen är installerad och tillgänglig på den lokala datorn med instansnamnet SqlExpress och att du har skapat SQL Server-inloggningar som matchar de som anges i niska veze. Du kan behöva aktivera SQL Server-inloggningar om servern har konfigurerats med standardsäkerhetsinställningarna som endast tillåter Windows-autentisering. Ändra niska veze efter behov för att passa din miljö.
Exempel
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("---------------------------");
}
}