@@ -1257,15 +1257,40 @@ protected virtual void OnMatchingEventWritten(EventWrittenEventArgs eventData)
12571257
12581258 public readonly ref struct XEventScope : IDisposable
12591259 {
1260- private const int MaxXEventsLatencyS = 5 ;
1260+ # region Private Fields
12611261
1262+ // Maximum dispatch latency for XEvents, in seconds.
1263+ private const int MaxDispatchLatencySeconds = 5 ;
1264+
1265+ // The connection to use for all operations.
12621266 private readonly SqlConnection _connection ;
1263- private readonly ushort _durationInMinutes ;
1267+
1268+ // True if connected to an Azure SQL instance.
12641269 private readonly bool _isAzureSql ;
1270+
1271+ // True if connected to a non-Azure SQL Server version 17 or higher.
12651272 private readonly bool _isVersion17OrHigher ;
12661273
1274+ // Duration for the XEvent session, in minutes.
1275+ private readonly ushort _durationInMinutes ;
1276+
1277+ # endregion
1278+
1279+ # region Properties
1280+
1281+ // The name of the XEvent session, derived from the session name
1282+ // provided at construction time, with a unique suffix appended.
12671283 public string SessionName { get ; }
12681284
1285+ #endregion
1286+
1287+ #region Construction
1288+
1289+ // Construct with the specified parameters.
1290+ //
1291+ // This will use the connection to query the server properties and
1292+ // setup and start the XEvent session.
1293+ //
12691294 public XEventScope (
12701295 string sessionName ,
12711296 // The connection must already be open.
@@ -1284,13 +1309,56 @@ public XEventScope(
12841309 // SQL Azure only supports database-scoped XEvent sessions
12851310 _isAzureSql = GetSqlServerProperty ( connection , ServerProperty . EngineEdition ) == "5" ;
12861311 _isVersion17OrHigher = int . Parse ( GetSqlServerProperty ( connection , ServerProperty . ProductMajorVersion ) ) >= 17 ;
1312+
1313+ // Setup and start the XEvent session.
1314+ string sessionLocation = _isAzureSql ? "DATABASE" : "SERVER" ;
12871315
1288- SetupXEvent ( eventSpecification , targetSpecification ) ;
1316+ // Both Azure SQL and SQL Server 2025 (v17.x) and higher support
1317+ // setting a maximum duration for the XEvent session.
1318+ string duration =
1319+ _isAzureSql || _isVersion17OrHigher
1320+ ? $ "MAX_DURATION={ _durationInMinutes } MINUTES,"
1321+ : string . Empty ;
1322+
1323+ string xEventCreateAndStartCommandText =
1324+ $@ "CREATE EVENT SESSION [{ SessionName } ] ON { sessionLocation }
1325+ { eventSpecification }
1326+ { targetSpecification }
1327+ WITH (
1328+ { duration }
1329+ MAX_MEMORY=16 MB,
1330+ EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
1331+ MAX_DISPATCH_LATENCY={ MaxDispatchLatencySeconds } SECONDS,
1332+ MAX_EVENT_SIZE=0 KB,
1333+ MEMORY_PARTITION_MODE=NONE,
1334+ TRACK_CAUSALITY=ON,
1335+ STARTUP_STATE=OFF)
1336+
1337+ ALTER EVENT SESSION [{ SessionName } ] ON { sessionLocation } STATE = START " ;
1338+
1339+ using SqlCommand createXEventSession = new SqlCommand ( xEventCreateAndStartCommandText , _connection ) ;
1340+ createXEventSession . ExecuteNonQuery ( ) ;
12891341 }
12901342
1343+ // Disposal stops and drops the XEvent session.
12911344 public void Dispose ( )
1292- => DropXEvent ( ) ;
1345+ {
1346+ string dropXEventSessionCommand = _isAzureSql
1347+ ? $ "IF EXISTS (select * from sys.dm_xe_database_sessions where name ='{ SessionName } ')" +
1348+ $ " DROP EVENT SESSION [{ SessionName } ] ON DATABASE"
1349+ : $ "IF EXISTS (select * from sys.dm_xe_sessions where name ='{ SessionName } ')" +
1350+ $ " DROP EVENT SESSION [{ SessionName } ] ON SERVER";
1351+
1352+ using SqlCommand command = new SqlCommand ( dropXEventSessionCommand , _connection ) ;
1353+ command . ExecuteNonQuery ( ) ;
1354+ }
1355+
1356+ #endregion
12931357
1358+ #region Public Methods
1359+
1360+ // Query the XEvent session for its collected events, returning them
1361+ // as an XML document.
12941362 public System . Xml . XmlDocument GetEvents ( )
12951363 {
12961364 string xEventQuery = _isAzureSql
@@ -1307,7 +1375,7 @@ INNER JOIN sys.dm_xe_sessions AS xe
13071375
13081376 using SqlCommand command = new SqlCommand ( xEventQuery , _connection ) ;
13091377
1310- Thread . Sleep ( MaxXEventsLatencyS * 1000 ) ;
1378+ Thread . Sleep ( MaxDispatchLatencySeconds * 1000 ) ;
13111379
13121380 string ? targetData = command . ExecuteScalar ( ) as string ;
13131381 Assert . NotNull ( targetData ) ;
@@ -1318,43 +1386,7 @@ INNER JOIN sys.dm_xe_sessions AS xe
13181386 return xmlDocument ;
13191387 }
13201388
1321- private void SetupXEvent ( string eventSpecification , string targetSpecification )
1322- {
1323- string sessionLocation = _isAzureSql ? "DATABASE" : "SERVER" ;
1324-
1325- // TODO: Does Azure SQL support setting duration as well?
1326- string duration = _isVersion17OrHigher ? $ "MAX_DURATION={ _durationInMinutes } MINUTES," : string . Empty ;
1327-
1328- string xEventCreateAndStartCommandText = $@ "CREATE EVENT SESSION [{ SessionName } ] ON { sessionLocation }
1329- { eventSpecification }
1330- { targetSpecification }
1331- WITH (
1332- { duration }
1333- MAX_MEMORY=16 MB,
1334- EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
1335- MAX_DISPATCH_LATENCY={ MaxXEventsLatencyS } SECONDS,
1336- MAX_EVENT_SIZE=0 KB,
1337- MEMORY_PARTITION_MODE=NONE,
1338- TRACK_CAUSALITY=ON,
1339- STARTUP_STATE=OFF)
1340-
1341- ALTER EVENT SESSION [{ SessionName } ] ON { sessionLocation } STATE = START " ;
1342-
1343- using SqlCommand createXEventSession = new SqlCommand ( xEventCreateAndStartCommandText , _connection ) ;
1344- createXEventSession . ExecuteNonQuery ( ) ;
1345- }
1346-
1347- private void DropXEvent ( )
1348- {
1349- string dropXEventSessionCommand = _isAzureSql
1350- ? $ "IF EXISTS (select * from sys.dm_xe_database_sessions where name ='{ SessionName } ')" +
1351- $ " DROP EVENT SESSION [{ SessionName } ] ON DATABASE"
1352- : $ "IF EXISTS (select * from sys.dm_xe_sessions where name ='{ SessionName } ')" +
1353- $ " DROP EVENT SESSION [{ SessionName } ] ON SERVER";
1354-
1355- using SqlCommand command = new SqlCommand ( dropXEventSessionCommand , _connection ) ;
1356- command . ExecuteNonQuery ( ) ;
1357- }
1389+ #endregion
13581390 }
13591391
13601392 /// <summary>
0 commit comments