jeton d'annulation sur Dapper

c# dapper orm

Question

J'utilise Dapper 1.31 de Nuget. J'ai cet extrait de code très simple,

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

Lorsque j'appuie sur F12 sur QueryAsync , cela me dirige vers

public static Task<IEnumerable<T>> QueryAsync<T>
     (
        this IDbConnection cnn, 
        string sql, 
        dynamic param = null, 
        IDbTransaction transaction = null, 
        int? commandTimeout = null, 
        CommandType? commandType = null
     );

Il n'y a pas de CancellationToken à sa signature.

Des questions:

  • Pourquoi l'extrait de code est-il complètement constructible en supposant qu'il n'y a pas d'erreur de compilation sur la solution entière?
  • Pardonnez-moi, car je ne peux pas tester si appeler tokenSource.Cancel() annulerait vraiment la méthode car je ne sais pas comment générer une longue requête SQL. Est-ce que le .Cancel() annule vraiment la méthode et lance OperationCancelledException ?

Je vous remercie!

Réponse acceptée

Vous transmettez le jeton d'annulation en tant qu'objet de paramètre; ça ne marchera pas.

Les premières méthodes asynchrones dans dapper n'ont pas exposé de jeton d'annulation; Lorsque j'ai essayé de les ajouter en tant que paramètre facultatif (en tant que surcharge séparée, pour éviter de casser des assemblys existants), les problèmes de compilation liés à la «méthode ambiguë» étaient très confus . Par conséquent, j'ai dû exposer cela via une API distincte; entrez CommandDefinition :

val = (await conn.QueryAsync<int>(
    new CommandDefinition(query, cancellationToken: tokenSource.Token)
).FirstOrDefault();

Cela fait ensuite passer le jeton d’annulation le long de la chaîne à tous les endroits attendus; c'est le travail du fournisseur ADO.NET de l' utiliser réellement, mais; cela semble fonctionner dans la plupart des cas. Notez que cela peut entraîner une SqlException plutôt qu'une OperationCancelledException si l'opération est en cours. Cela revient au fournisseur ADO.NET, mais cela a du sens: vous auriez pu interrompre quelque chose d'important; il apparaît comme un problème de connexion critique.

En ce qui concerne les questions:

Pourquoi l'extrait de code est-il complètement constructible en supposant qu'il n'y a pas d'erreur de compilation sur la solution entière?

Parce que ... c'est C # valide, même s'il ne fait pas ce que vous attendez.

Pardonnez-moi, car je ne peux pas tester si appeler tokenSource.Cancel () annulerait vraiment la méthode car je ne sais pas comment générer une longue requête SQL. Est-ce que le .Cancel () annule vraiment la méthode et lance OperationCancelledException?

ADO.NET spécifique au fournisseur, mais oui, cela fonctionne généralement. Comme exemple de "comment générer une requête SQL longue"; la commande waitfor delay sur SQL server est quelque peu utile ici et est ce que j'utilise dans les tests d'intégration.


Réponse populaire

Vous pouvez corriger SqlMapper.cs dans Dapper lib en ajoutant ces lignes:

    internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader)
    {
        var cmd = cnn.CreateCommand();

#if ASYNC
        // We will cancel our IDbCommand
        CancellationToken.Register(() => cmd.Cancel());
#endif

Reconstruisez votre propre librairie Dapper et profitez de :)




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi