带有异步Dapper方法的CancellationToken? [英] CancellationToken with async Dapper methods?

查看:215
本文介绍了带有异步Dapper方法的CancellationToken?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆