SQL Server statement not really executed by async C# code
-
21-12-2019 - |
Pregunta
I'm probably missing something simple. I'm trying to create load tests that call a stored procedure asynchronously and I see the calls being made in SQL Profiler but they're not actually executing. I've reduced my code to the sample below, which will result in the command showing in Profiler as if it ran even though it didn't. If you change AsynchronousProcessing to false and ExecuteScalarAsync to ExecuteScalar it works as expected.
public static void DeleteRow()
{
var cs = new SqlConnectionStringBuilder();
cs.DataSource = @"SQLDEV";
cs.InitialCatalog = "MyDB";
cs.IntegratedSecurity = true;
cs.AsynchronousProcessing = true;
string connectionString = cs.ToString();
int rowID = 127279530;
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(String.Concat(@"exec [dbo].[DeleteRow] @RowId=", rowID.ToString()), conn);
cmd.CommandType = System.Data.CommandType.Text;
cmd.ExecuteScalarAsync();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
EDIT: Here's some of my original code to show what I'm trying to do.
IEnumerable<int> list = Enumerable.Range(127279517, 14);
_queued = new ConcurrentQueue<int>(list);
Task task1 = Task.Run(() => ProcessQueue());
Task task2 = Task.Run(() => ProcessQueue());
Task task3 = Task.Run(() => ProcessQueue());
Task task4 = Task.Run(() => ProcessQueue());
Task task5 = Task.Run(() => ProcessQueue());
Task.WaitAll(task1, task2, task2, task3, task4, task5);
and
while (_queued.TryDequeue(out rowId))
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(String.Concat(@"exec [dbo].[DeleteRow] @RowId=", rowId.ToString()), conn);
cmd.CommandType = System.Data.CommandType.Text;
NonBlockingConsole.WriteLine(cmd.CommandText);
cmd.ExecuteScalarAsync();
}
}
Solución
cmd.ExecuteScalarAsync()
returns a task. You should probably await it and make DeleteRow
itself return a task. If you are at it use OpenAsync
to go fully async.
On the other hand you probably don't need async at all. Just use the synchronous version of ExecuteScalarAsync
which is ExecuteScalar
.