C# : Cancelling MySqlCommand using CancellationToken giving NULLReferenceException

标签 c# mysql .net mysqlcommand

我试图使用 CancellationToken 取消 MySqlCommand。当未请求取消时,查询执行成功。

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。

enter image description here

我通过以下方式调用上述方法

deletedRowsInLastIteration = await 
    mySqlHelperService.ExecuteNonQueryAsync(
       connectionString,
       query, 
       cancellationToken);

如果我尝试

cancellationToken.ThrowIfCancellationRequested();

在调用ExecuteNonQueryAsync()方法之前,它可以工作。但是MySqlCommand的取消不起作用。

这是堆栈跟踪

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\repos\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)

最佳答案

您不应使用Task.Run 将同步方法转换为异步方法。充其量,这会浪费一个线程来等待某些 IO 操作完成。

MySqlCommand 有一个接受取消 token 的 ExecuteNonQueryAsync 方法。 MySqlConnection 本身有一个 OpenAsync 方法。您应该将代码更改为:

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;
}

关于C# : Cancelling MySqlCommand using CancellationToken giving NULLReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59404269/

相关文章:

C#:子类列表 <Something>?

c# - 数据库插入后如何返回唯一ID

c# - 无法使用网络凭据

使用 BCrypt 的 PHP 登录身份验证

mysql - 如何根据时间间隔生成序列号

c# - 没有 csc.exe 的 XML 序列化

C#字符串不包含可能吗?

教程中的 MySQL SQL 查询问题

.net - DataTable.Clear 和 DataTable.Rows.Clear 之间有区别吗?

c# - WinForms - Form.DoubleBuffered 属性会影响放置在该窗体上的控件吗?