2016-11-29 22 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は、私が50秒を取って、要求がまだ評価されますことを、SEができ、30です。

非同期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への呼び出しをdapperにするために渡す

    • キャンセルトークン:あなたが関係する何かをすることができればしかし、私は疑問に思います。 DapperのタスクとWhenAnyから戻ってきた遅延タスク
    • チェックに合格WhenAny - それがあった場合の遅延を、その後のキャンセルによって生じたいかなる例外は
    • きれいに処理されることを確実にキャンセルを通知し、あなた自身のタイムアウト
    • を投げます

    DBプロバイダがタイムアウトをネイティブに尊重しない場合、ライブラリがカプセル化する必要があります。その場合はおそらくライブラリーがこれを正しく行うことができます(ライブラリーのみがコマンドにアクセスできるため)

  • 関連する問題