我正在使用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 throw OperationCancelledException?
谢谢!
推荐答案您正在将取消令牌作为参数传递宾语;
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?
发布评论