我使用的是 Nuget 的 Dapper 1.31。我有这个非常简单的代码片段,
string connString = "";
string query = "";
int val = 0;
CancellationTokenSource tokenSource = new CancellationTokenSource();
using (IDbConnection conn = new SqlConnection(connString))
{
conn.Open();
val = (await conn.QueryAsync<int>(query, tokenSource.Token)).FirstOrDefault();
}
当我在 QueryAsync
上按 F12 时,它指向我
public static Task<IEnumerable<T>> QueryAsync<T>
(
this IDbConnection cnn,
string sql,
dynamic param = null,
IDbTransaction transaction = null,
int? commandTimeout = null,
CommandType? commandType = null
);
其签名上没有CancellationToken
。
问题:
- 为什么该代码段是完全可构建的假设整个解决方案没有编译器错误?
- 请原谅我无法测试调用
tokenSource.Cancel()
是否真的会取消该方法,因为我不知道如何生成长时间运行的 sql 查询。.Cancel()
真的会取消方法并抛出OperationCancelledException
吗?
谢谢!
最佳答案
您将取消 token 作为参数对象传递;那是行不通的。
dapper 中的第一个异步方法没有公开取消 token ;当我尝试将它们添加为可选参数时(作为单独的重载,以避免破坏现有程序集),things got very confused with "ambiguous method" compilation problems .因此,我不得不通过一个单独的 API 公开它;输入 CommandDefinition
:
val = (await conn.QueryAsync<int>(
new CommandDefinition(query, cancellationToken: tokenSource.Token)
).FirstOrDefault();
然后将取消 token 沿链传递到所有预期的位置; ADO.NET 提供者的工作是实际使用它,但是;它似乎在大多数情况下都有效。请注意,如果操作正在进行,它可能会导致 SqlException
而不是 OperationCancelledException
;这又取决于 ADO.NET 提供程序,但很有意义:您可能打断了一些重要的事情;它表面上是一个关键的连接问题。
至于问题:
Why is the snippet completely buildable assuming that there is no compiler error on the whole solution?
因为...它是有效的 C#,即使它没有达到您的预期。
Forgive me as I cannot test if calling tokenSource.Cancel() would really cancel the method because I don't know how to generate long running sql query. Will the .Cancel() really cancels the method and throws OperationCancelledException?
特定于 ADO.NET 提供程序,但它通常有效。作为“如何生成长时间运行的 sql 查询”的示例; SQL Server 上的 waitfor delay
命令在这里有些用处,也是我在集成测试中使用的命令。
关于c# - 使用异步 Dapper 方法的 CancellationToken?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25540793/