2017-11-10 7 views
0

私はMS referenceでDbDataReader(DbCommand)のコードを見ていますが、ReadAsync()メソッドでは非同期なものがわかりません。System.Data.Common.DbDataReader.ReadAsyncのasyncとは何ですか?

virtual public Task<bool> ReadAsync(CancellationToken cancellationToken) { 
     if (cancellationToken.IsCancellationRequested) { 
      return ADP.CreatedTaskWithCancellation<bool>(); 
     } 
     else { 
      try { 
       return Read() ? ADP.TrueTask : ADP.FalseTask; 
      } 
      catch (Exception e) { 
       return ADP.CreatedTaskWithException<bool>(e); 
      } 
     } 
    } 

ReadAsyncメソッドは、Readメソッドを呼び出して完全なタスクを返します。 これは、呼び出しを直接呼び出しているのと同じ方法で呼び出しスレッドをブロックしませんか?

私はDbCommand ExecuteReaderAsyncと他のメソッドで同じパターンに気付きました。彼らは同期バージョンを呼び出し、完了したタスクを返します。

私はここで何が欠けていますか?

UPDATE:@PeterBonsがうまく説明されているので、何も見逃さなかった(the documentationでも)。私はまだそれが好きではありませんが、それは私の問題です。

+2

いくつかのプロバイダ(一般的なプロバイダを含む)は、データベースとの実際の非同期通信をサポートしていないため、この実装を継承しています。そうした人は、実際の実装を上書きして提供します。はい、これらのメソッドを抽象化することもできますが、これをサポートしていないプロバイダには、独自の偽装実装を提供しないようにする別の設計決定が行われました。 – Evk

答えて

4

抽象クラスの仮想メソッドがあります。実際の非同期作業を(将来の)実装で実行できるようにするには、それを可能にするメソッドシグネチャを定義する必要があります。したがって、TaskまたはTask<T>が返されます。タスクを使用するだけでは非同期が行われないことを覚えておいてください。

この例の仮想メソッドで戻り値の型を使用すると、ReadAsyncの実装で実際の非同期動作を提供するためにDbDataReaderから派生する他のクラスを容易にすることができます。あなたがメソッドのシグネチャを変更することなく、あなたが今、非同期および非非同期実装を持つことができます見ることができるように

例えば、真の非同期実装が

class TrueAsyncReader : DbDataReader 
{ 
    ... 

    public override async Task<bool> ReadAsync(CancellationToken cancellationToken) 
    { 
     ... 

     return await ReadFromDbAsync(); 
    } 
} 

ような何かを行うことができます。

非同期メソッドから簡単に同期コードを呼び出すことができるので、これはやり方です。同期メソッドから非同期コードを呼び出すことは不可能です。

タスクを返す必要がある非同期実装の場合は、Task.FromResult<T>またはTask.CompletedTaskのようなものを返すことができます。これはブロックされません。

await Task.CompletedTask for what?

を要約するも参照してください:デフォルトの実装では、メソッドのシグネチャを変更することなく、非同期が、派生クラスができる何もしません。

+0

クラスは抽象クラスですが、メソッドはそうではありません。実際のオブジェクトをDbDataReaderにキャストし、このメソッドを呼び出すことができます。私の質問は、それが本当に非同期なのですか? – gajo357

+3

@ gajo357メソッドはバーチャルなので、実装ではオーバーライドできます。デフォルトの実装は非同期ではありません。オーバーライドメソッドはすべて非同期にすることができます。質問に表示されるコードは同期して実行され、非同期で実行されるコードはありません。 'Task'を使うだけでは非同期的なことはありません。 –

+2

メソッドが非同期であり、メソッドが待ち受けることに大きな違いがあります。私はここで編集する価値があると感じています。 – Gusdor

関連する問題