2012-11-12 10 views
5

私はEF6の非同期メソッドの新機能を見てきました。私は例を見つける。EFでのこの2つの非同期呼び出しの違いは何ですか?

この最初の方法は、例えばEF5で、通常の呼び出しです:

public Store FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).First(); 
    } 
} 

そして新しいコール、EF6で非同期メソッドで。 、

public async Task<Store> MyAsyncMethod(DbGeography location) 
{ 
    return await Task.Run(() => FindClosestStore()); 
} 

私が意味する、私は最初のメソッドを呼び出すためにTask.Runを使用することができます:

public async Task<Store> FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return await (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).FirstAsync(); 
    } 
} 

しかし、私は(syntaxisが、私はメモリでそれを行う、およそ10mlの液体フッ化水素を圧入である)次の操作を行うことができますそれは結果を待つために非同期ではありません。現時点では、私はEFだけでなく、どのメソッドでも非同期呼び出しを使用する方法です。これは非同期呼び出しでも、EF6非同期メソッドを使用すると本当に非同期呼び出しとなりますか?

EF6の新しいバージョンで非同期メソッドが必要なのはなぜですか?単純化のためだけですか?

+0

asyncは構文の砂糖です.Net 4.5の新機能は、ContinueWithを使って同じことをすることができます –

答えて

9

ここでの違いはコードがどのように待っているかです。このコードので

public async Task<Store> FindClosestStore(DbGeography location) 
{ 
    using (var context = new StoreContext()) 
    { 
     return await (from s in context.Stores 
      orderby s.Location.Distance(location) 
      select s).FirstAsync(); 
    } 
} 

EFは、データベースに対してクエリを発行し、返します。

結果が戻ったら、タスクは完了し、待機ブロックは引き続き実行されます。

つまり、応答を待っている.NET自体にスレッドはありません。 結果が到着したときに.NETに通知するdbドライバからのより低いレベルのコールバックがあります(うまくいけば)。

(これは、.NETで動作し、私はADO.NET非同期のために同じことを前提とし、少なくともどのように他のIO非同期である)

その他の場合:

public async Task<Store> MyAsyncMethod(DbGeography location) 
{ 
    return await Task.Run(()=> FindClosestStore()); 
} 

スレッドがありますDBからの応答を待っています。つまり、あなたはIOをブロックしますが、それはあなたのtask.runトリックで消費者から隠されます。

どちらのケースも消費者にとって同じように動作しますが、違いは、最後の例ではリソースが不足していることです。

+0

私は非同期/待機の使用が新しいスレッドを使用する必要性を避けると思います。時々作成され、時には(縫合に依存しない)作成されます。実際、WCFでは、要求が処理されている間にリソースを解放するためにasync/awaitパターンが使用されます。 EFでは同じように動作しますが、要求が実行されている間はリソースを解放しますか? –

+2

最後のコードサンプルでは、​​非同期非EFメソッドを使用するため、ブロッキングスレッドが存在します。その呼び出しをasync/awaitブロックでラップしても。あれは。 "FindClosestStore()"は、舞台裏でスレッドをブロックします –

+0

これはasync/awaitが使用されているときにWCFで発生しませんか? EF5で非同期を使用する方法はありますか? –

関連する問題