带有异步Dapper方法的CancellationToken? [英] CancellationToken with async Dapper methods?
问题描述
我正在使用Nuget的Dapper 1.31。我有一个非常简单的代码段,
I'm using Dapper 1.31 from Nuget. I have this very simple code snippet,
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();
}
当我在<$ c $上按 F12 时c> QueryAsync ,它将我指向
When I press F12 on QueryAsync
, it points me to
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
?
- Why is the snippet completely buildable assuming that there is no compiler error on the whole solution?
- Forgive me that I cannot test if calling
tokenSource.Cancel()
would really cancel the method because I don't know how to generate a long running sql query. Will the.Cancel()
really cancel the method and throwOperationCancelledException
?
谢谢!
推荐答案
您正在将取消令牌作为参数传递宾语;
You are passing the cancellation token as the parameter object; that won't work.
dapper中的第一个异步方法没有公开取消令牌;当我尝试将它们添加为可选参数(作为单独的重载,以避免破坏现有的程序集)时,事情与模棱两可的方法编译问题非常混淆。因此,我不得不通过单独的API公开它;输入 CommandDefinition
:
The first async methods in dapper did not expose a cancellation token; when I tried to add them as an optional parameter (as a separate overload, to avoid breaking existing assemblies), things got very confused with "ambiguous method" compilation problems. Consequently, I had to expose this via a separate API; enter CommandDefinition
:
val = (await conn.QueryAsync<int>(
new CommandDefinition(query, cancellationToken: tokenSource.Token)
).FirstOrDefault();
然后将取消令牌向下传递到所有预期的位置; ADO.NET提供程序的工作是实际使用,但是;它似乎在在大多数情况下,请注意,如果操作正在进行,它可能会导致 SqlException
而不是 OperationCancelledException
;取决于ADO.NET提供程序,但在很大程度上有道理:您可能已经中断了一些重要的事情;它成为一个关键的连接问题。
This then passes the cancellation-token down the chain to all the expected places; it is the job of the ADO.NET provider to actually use it, but; it seems to work in most cases. Note that it can result in a SqlException
rather than an OperationCancelledException
if the operation is in progress; this again is down to the ADO.NET provider, but makes a lot of sense: you could have interrupted something important; it surfaces as a critical connection issue.
对于这些问题:
假设整个解决方案都没有编译器错误,为什么该代码段是完全可构建的?
Why is the snippet completely buildable assuming that there is no compiler error on the whole solution?
因为...它是有效的C#,即使它不是d
Because... it is valid C#, even if it doesn't do what you expect.
请原谅我,因为我无法测试调用tokenSource.Cancel()是否真的取消了该方法,因为我没有知道如何生成长时间运行的sql查询。 .Cancel()会真正取消该方法并引发OperationCancelledException吗?
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
命令在这里有些有用,这也是我在集成测试中使用的。
ADO.NET provider-specific, but yes it usually works. As an example of "how to generate long running sql query"; the waitfor delay
command on SQL server is somewhat useful here, and is what I use in the integration tests.
这篇关于带有异步Dapper方法的CancellationToken?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!