c# - micro - token de cancelación en Dapper
dapper vs entity framework (2)
Está pasando el token de cancelación como el objeto de parámetro; eso no funcionará
Los primeros métodos asíncronos en dapper no exponen un token de cancelación; cuando intenté agregarlos como un parámetro opcional (como una sobrecarga separada, para evitar romper conjuntos existentes), las cosas se confundieron con los problemas de compilación de "métodos ambiguos" . En consecuencia, tuve que exponer esto a través de una API separada; ingrese CommandDefinition
:
val = (await conn.QueryAsync<int>(
new CommandDefinition(query, cancellationToken: tokenSource.Token)
).FirstOrDefault();
Esto luego pasa la ficha de cancelación por la cadena a todos los lugares esperados; es el trabajo del proveedor ADO.NET usarlo realmente, pero; parece funcionar en la mayoría de los casos. Tenga en cuenta que puede dar como resultado una SqlException
lugar de una OperationCancelledException
si la operación está en curso; esto nuevamente se debe al proveedor de ADO.NET, pero tiene mucho sentido: podría haber interrumpido algo importante; surge como un problema de conexión crítico.
En cuanto a las preguntas:
¿Por qué el fragmento es completamente edificable, suponiendo que no existe un error de compilación en toda la solución?
Porque ... es válido C #, incluso si no hace lo que espera.
Perdóneme ya que no puedo probar si llamar a tokenSource.Cancel () realmente cancelaría el método porque no sé cómo generar consultas SQL de ejecución larga. ¿El .Cancel () realmente cancela el método y lanza OperationCancelledException?
Específico del proveedor de ADO.NET, pero sí, generalmente funciona. Como un ejemplo de "cómo generar consultas SQL de larga ejecución"; el comando waitfor delay
en SQL server es algo útil aquí, y es lo que uso en las pruebas de integración.
Estoy usando Dapper 1.31 de Nuget. Tengo este fragmento de código muy 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();
}
Cuando QueryAsync
F12 en QueryAsync
, me señala
public static Task<IEnumerable<T>> QueryAsync<T>
(
this IDbConnection cnn,
string sql,
dynamic param = null,
IDbTransaction transaction = null,
int? commandTimeout = null,
CommandType? commandType = null
);
No hay CancellationToken
en su firma.
Preguntas:
- ¿Por qué el fragmento es completamente edificable, suponiendo que no existe un error de compilación en toda la solución?
- Perdóneme ya que no puedo probar si llamar a
tokenSource.Cancel()
realmente cancelaría el método porque no sé cómo generar consultas SQL de ejecución larga. ¿El.Cancel()
realmente cancela el método y lanzaOperationCancelledException
?
¡Gracias!
Puede corregir SqlMapper.cs en Dapper lib agregando estas líneas:
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
Reconstruye tu propia lib de Dapper y disfruta :)