Open
Description
Dapper will fail with such Test
async Task<IEnumerable<Product>> Test()
{
CancellationTokenSource cancel = new CancellationTokenSource();
try
{
const string sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name
union all select 1 as id, 'abc' as name, 2 as id, 'def' as name";
var productQuery = await connection.QueryAsync<Product, Category, Product>(new CommandDefinition(sql, cancellationToken: cancel.Token), (p, c) => {
p.Category = c;
//we cancel it in the middle of reading
cancel.Cancel();
return p;
}).ConfigureAwait(false);
return productQuery;
}
catch (Exception agg)
{
//should be SqlException with message canceled
}
return null;
}
public async Task TestCancelInReaderReadAsync()
{
var res = await Test();
res.IsEqualTo(null);
}
solution:
replace all code like(in SQlMapper.Async.cs):
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
{
/*...*/
}
with
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
{
using (var reg = command.CancellationToken.Register(() => cmd.Cancel()))
{
/*...*/
}
}
solution is simillar to this answer on SO but he is doing it at wrong place (and not dissposing the registration) ...