Я использую Dapper (версия 1.50.5) в веб-API ASP. NET, выполняя некоторые SQL асинхронно. Я заметил, что запрос не отменяется после того, как отмена инициирована клиентом.
Я знаю, что это был топи c раньше (например, CancellationToken с asyn c методами Dapper ? ), но даже после обращения к различным аналогичным статьям я не смог понять проблему или найти решение.
Вот несколько фрагментов кода.
Обратите внимание что
objectDirector.ReadAsync(id, cancellationToken);
передает отмену, принятую
ExecuteQueryAsync(CancellationToken cancellationToken)
Контроллер:
[HttpPost]
[Route("api/Forms/{id}/Data")]
[CompressFilter]
public async Task<IHttpActionResult> GetDataAsync(int id, CancellationToken cancellationToken)
{
if (!forms.IsAuthorized(id, uniqueId, Constants.Roles.Operator))
{
return StatusCode(HttpStatusCode.Forbidden);
}
if (!forms.Exists(id))
{
return NotFound();
}
var dynamicObjects = await objectDirector.ReadAsync(id, cancellationToken);
return Ok(dynamicObjects);
}
Запрос исполняемый код:
public async Task<IEnumerable<dynamic>> ExecuteQueryAsync(CancellationToken cancellationToken)
{
var tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
using (var connection = new SqlConnectionFactory().CreateConnection(Form.DatabaseId))
{
try
{
tokenSource.CancelAfter(new TimeSpan(0, 4, 0));
await connection.OpenAsync(tokenSource.Token);
var sql = SqlQueryBuilder.ToString();
var command = new CommandDefinition(sql, commandTimeout: 240, cancellationToken: tokenSource.Token);
return await connection.QueryAsync(command);
}
catch (SqlException exception)
{
var messageTemplate = "Exception: {Method}, {DataSource}, {Database}; Form: {Id}, {Name}";
Logger.Error(exception, messageTemplate, "Dynamic Object Reader: Execute Query", connection.DataSource, connection.Database, Form.Id, Form.Name);
throw;
}
finally
{
tokenSource.Dispose();
}
}
}
Когда я заменяю код выполнения запроса на al oop, который проверяет статус отмены, а затем завершает процесс, если этот статус изменился, он работает, как ожидалось. Однако, когда я выполняю приведенный выше код, он не завершает выполнение запроса к базе данных, ни для запроса отмены из клиентского приложения, ни для отмены через 4 минуты.