-
Notifications
You must be signed in to change notification settings - Fork 314
Description
Description
When using CancellationToken, an exception raised by sqlCommand.ExecuteNonQueryAsync() causes memory leaks.
When not using CancellationToken, an exception raised by sqlCommand.ExecuteNonQueryAsync() does not cause any memory leaks.
More details about context
When we run a background process which executes sql commands in regular (scheduled) manner (execute-sleep-execute), and using global CancellationToken, process would go out of memory if some commands generate errors.
To reproduce
Run the code below. Comment and uncomment calls of ExecuteNonQueryAsync to see the difference between using CancellationToken and not using it.
CancellationToken stoppingToken = new CancellationTokenSource().Token;
using var connection = new SqlConnection("Data Source=localhost");
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var command = connection.CreateCommand();
string myString = new string('*', 1000000);
command.CommandText = "select * from Table1 where Name = @p1";
var tvpParam = command.Parameters.AddWithValue("@p1", myString);
tvpParam.SqlDbType = SqlDbType.VarChar;
//memory leak
await command.ExecuteNonQueryAsync(stoppingToken);
//no memory leak
//await command.ExecuteNonQueryAsync();
}
catch
{
}
}
Expected behavior
When using CancellationToken, memory usage should be the same as in the case of not using CancellationToken
Further technical details
Microsoft.Data.SqlClient version: (4.1.0)
.NET target: (Net 5 and 6)
Operating system: (Windows)