2016-11-29 13 views
2

Dapper.NET에서 비동기 API를 사용하면 확장 메서드에서 전달하는 명령 시간 제한 값이 준수되지 않는다는 것을 알게되었습니다. 그런 다음 SqlCommand.CommandTimeout의 MSDN documentation이 나타 났으며 이것이 "지원되지 않는"것으로 보입니다.Dapper.NET 비동기 API를 사용할 때 CommandTimeout을 존중하는 방법

CommandTimeout 속성은 BeginExecuteReader와 같은 비동기 메서드 호출 중에 무시됩니다.

기본 클래스에서 다음 메소드를 사용하고 있습니다.

public async Task<int> ExecuteAsync(string sql, object param = null, 
      CommandType commandType = CommandType.Text, int? commandTimeout = null, IDbTransaction transaction = null) 
{ 
    using (var connection = Connection) 
    { 
     Task<int> queryTask = connection.ExecuteAsync(sql, param, transaction, commandTimeout ?? CommandTimeoutDefault, commandType); 
     int result = await queryTask.ConfigureAwait(false); 
     connection.Close(); 
     connection.Dispose(); 
     return result; 
    } 
} 

public async Task<IEnumerable<TEntity>> QueryAsync(string sql, object param = null, 
      CommandType commandType = CommandType.Text, int? commandTimeout = null, IDbTransaction transaction = null) 
{ 
    using (var connection = Connection) 
    { 
     Task<IEnumerable<TEntity>> queryTask = connection.QueryAsync<TEntity>(sql, param, transaction, commandTimeout ?? CommandTimeoutDefault, commandType); 
     IEnumerable<TEntity> data = await queryTask.ConfigureAwait(false); 
     connection.Close(); 
     connection.Dispose(); 
     return data; 
    } 
} 

CommandTimeoutDefault 나는, 30 SE 50 초 복용 요청이 아직 평가 될 것이다을 할 수있다.

비동기 Dapper.NET API를 사용하여 시간 초과 간격으로 연결을 끊고 처리하는 방법에 대한 의견이 있으십니까?

+0

사소한 무관 한 것 : Close/Dispose 필요 - 기존 코드는 이미'using'을 통해 이러한 작업을 수행합니다. –

답변

0

Dapper의 현재 버전에서 비동기 메소드에서 호출되는 함수입니다. CommandTimeout이 충분히 존경받는 것을 볼 수 있습니다.

internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader) 
    { 
     IDbCommand command = cnn.CreateCommand(); 
     Action<IDbCommand> init = CommandDefinition.GetInit(command.GetType()); 
     if (init != null) 
     init(command); 
     if (this.Transaction != null) 
     command.Transaction = this.Transaction; 
     command.CommandText = this.CommandText; 
     if (this.CommandTimeout.HasValue) 
     { 
     command.CommandTimeout = this.CommandTimeout.Value; 
     } 
     else 
     { 
     int? commandTimeout = SqlMapper.Settings.CommandTimeout; 
     if (commandTimeout.HasValue) 
     { 
      IDbCommand dbCommand = command; 
      commandTimeout = SqlMapper.Settings.CommandTimeout; 
      int num = commandTimeout.Value; 
      dbCommand.CommandTimeout = num; 
     } 
     } 
     System.Data.CommandType? commandType = this.CommandType; 
     if (commandType.HasValue) 
     { 
     IDbCommand dbCommand = command; 
     commandType = this.CommandType; 
     int num = (int) commandType.Value; 
     dbCommand.CommandType = (System.Data.CommandType) num; 
     } 
     if (paramReader != null) 
     paramReader(command, this.Parameters); 
     return command; 
    } 

enter image description here

+0

OP가 말한 것은 SqlClient가 타임 아웃을 존중하지 않는다는 것입니다. –

+0

동일한 문제가있었습니다. 그리고 dapper API의 동기 버전을 사용했습니다. 하지만 어쨌든 모든 비동기 작업을 비동기 적으로 수행 할 수 있습니다. – Dmitry

0

이하는 SqlClient이 자신과 거래를한다는 것을 애 태우게입니다! 당신이 당신의 시간 제한

  • 작업에 대한 호출로 (그들을 받아)
  • Task.Delay에게 전화를 말끔에 전달

    • 취소 토큰 : 당신이 관련된 일을 할 수 있다면 그러나, 나는 궁금하다. 날씬한 작업 및 WhenAny에서 돌아온 지연 작업
    • 검사에 통과 WhenAny - 그것이 경우 지연 후 취소로 인한 예외는
    • 깨끗하게 처리되어 있는지 확인 취소 신호를하고 자신의 시간 제한
    • 를 던져

    DB 제공자가 기본적으로 타임 아웃을 존중하지 않을 경우 라이브러리가 캡슐화해야하는 부분이 약간 있습니다. 어떤 경우에는 아마도 라이브러리 만 제대로 수행 할 수 있습니다 (라이브러리 만 명령에 액세스 할 수 있기 때문에)