C# : Cancelling MySqlCommand using CancellationToken giving NULLReferenceException
我试图使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public async Task<int> ExecuteNonQueryAsync(string connectionString, string query, CancellationToken cancellationToken) { int affectedRowsCount = 0; await Task.Run(() => { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand()) { connection.Open(); command.Connection = connection; cancellationToken.Register(() => command.Cancel()); command.CommandText = query; command.CommandTimeout = 0; affectedRowsCount = command.ExecuteNonQuery(); connection.Close(); } } }); return affectedRowsCount; } |
但是,当请求取消时,它会产生NullReferenceException。
无法弄清楚什么是NULL。
我正在通过以下方式调用上述方法
1 2 3 4 5 | deletedRowsInLastIteration = await mySqlHelperService.ExecuteNonQueryAsync( connectionString, query, cancellationToken); |
如果我尝试
1 | cancellationToken.ThrowIfCancellationRequested(); |
在调用
这是堆栈跟踪
System.NullReferenceException HResult=0x80004003 Message=Object
reference not set to an instance of an object. Source=MySql.Data
StackTrace: at
MySql.Data.MySqlClient.MySqlConnection.CancelQuery(Int32 timeout)
at MySql.Data.MySqlClient.MySqlCommand.Cancel() at
ProjectName.Common.MySqlHelperService.<>c__DisplayClass1_1.b__1()
in
C:\\Users\\username\\source\
epos\\ProjectName\\Applications\\ProjectName.Common\\MySqlHelperService.cs:line
55 at
System.Threading.CancellationToken.ActionToActionObjShunt(Object obj)
at
System.Threading.CancellationCallbackInfo.ExecutionContextCallback(Object
obj) at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.CancellationCallbackInfo.ExecuteCallback() at
System.Threading.CancellationTokenSource.CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments
args) at
System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean
throwOnFirstException)
您不应该使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public async Task<int> ExecuteNonQueryAsync(string connectionString, string query, CancellationToken cancellationToken) { using (MySqlConnection connection = new MySqlConnection(connectionString)) { using (MySqlCommand command = new MySqlCommand(query,connection)) { await connection.OpenAsync(); command.CommandTimeout = 0; var affectedRowsCount = await command.ExecuteNonQuery(cancellationToken); } } return affectedRowsCount; } |
您如何创建取消令牌,他的价值是什么?
这也是解决方案如何使用取消令牌取消sql命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | private CancellationTokenSource cts; private async void TestSqlServerCancelSprocExecution() { cts = new CancellationTokenSource(); try { await Task.Run(() => { using (SqlConnection conn = new SqlConnection("connStr")) { conn.InfoMessage += conn_InfoMessage; conn.FireInfoMessageEventOnUserErrors = true; conn.Open(); var cmd = conn.CreateCommand(); cts.Token.Register(() => cmd.Cancel()); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText ="dbo.[CancelSprocTest]"; cmd.ExecuteNonQuery(); } }); } catch (SqlException) { // sproc was cancelled } |
}
上面的代码来自这个问题,该问题也存在相同的问题,即取消令牌不会取消sql命令。