1

EF6をダウンロードしました(使用するためasync

だから私はこの簡単な方法を書きました:

  public async Task<List<int>> MyasyncMethod()
      {
          var locations = await MyDumpEntities.AgeGroups.Select(f=>f.endYear).ToListAsync();
          return locations;
       }

   ...Later...


  DumpEntities1 MyDumpEntities = new DumpEntities1();
  var data = MyDumpEntities.AgeGroups.ToListAsync();
  MyasyncMethod().ContinueWith(s => { Response.Write("f"); });
  MyDumpEntities.Dispose();

しかし、画面には何も表示されず、調べると次のdataように表示されます。

ここに画像の説明を入力

psこれは ToListAsync署名です ここに画像の説明を入力

何が欠けていますか?

4

3 に答える 3

3

問題のあるコメントと行に基づいて:

var data = MyDumpEntities.AgeGroups.ToListAsync();

タイプは何にdataなりますか?Task<List<AgeGroup>>. そうです、そうではありませんList<AgeGroup>。したがって、Page_Load非同期としてマークする必要があります(可能な場合):

public async void Page_Load(object sender, EventArgs e)
{
    using(var MyDumpEntities = new DumpEntities1())
    {
       var data = await MyDumpEntities.AgeGroups.ToListAsync();
    }     
}

または、何らかの方法で実行を待ちます (継続、ブロック待ち)。

別のこと (私が間違っている場合、他の誰かがそれを修正したいかもしれません) ですが、2 番目の呼び出しに継続を使用しているため、継続の外でコンテキストを破棄することに非常に注意を払います。コンテキストを先制的に破棄することが判明する場合があります。この特定のケースでは、継続でコンテキストを使用していませんが、疑わしいように見えます...

だから私はどちらかだろう

MyasyncMethod().ContinueWith(s => { Response.Write("f"); MyDumpEntities.Dispose();});

または、asyncそこでも使用します

var result = await MyasyncMethod();
Response.Write("f");
MyDumpEntities.Dispose();

Async="True"ページディレクティブに追加します

于 2013-07-11T07:25:38.410 に答える
2

他の人は、正しい解決策は を使用することだと指摘していますが、その理由awaitについての適切な説明がわかりません。

元のコードが間違っている理由は 2 つあります。まず、ContinueWithASP.NET アプリケーションでコンテキストをキャプチャせずに使用しているため、継続 (Response.Write呼び出し) には要求コンテキストがないため、書き込む応答がありません。

awaitの前にコンテキストをキャプチャし、awaitそれを使用して残りのメソッドを再開することで、これを処理します。この場合、AspNetSynchronizationContext現在のリクエスト/レスポンスを表す をキャプチャします。

もう 1 つの理由は、非同期コードが同時に実行されることです。したがって、MyasyncMethodは実行を開始し、その に到達しawait、未完了のタスクを に返しますPage_LoadPage_Load次に、そのタスクに継続をアタッチして実行を継続し、コンテキストを破棄します。ToListAsyncそのため、リクエストがまだ実行されている間にコンテキストが破棄される場合があります。

awaitが完了Page_Loadするまでメソッドを「一時停止」するため、これも修正されます。MyasyncMethod

async最後に、ASP.NET で使用する場合は、次の点も考慮する必要があります。

  1. .NET 4.5 をターゲットにする必要があります。使用しないでくださいMicrosoft.Bcl.Async
  2. targetFramework4.5 に設定するUseTaskFriendlySynchronizationContext、trueに設定する必要があります。
  3. (WebForms のみ) Page.Asynctrue に設定します。
  4. RegisterAsyncTaskの代わりに使用することを検討してくださいawait。私は通常、awaitメソッドごとに関心がより分離されていることを好みますが、ASP.NET チームが好むのは、ランタイムがすべての操作の完了を待機するRegisterAsyncTask後に単一の「同期」ポイントがあるためです。使い方はこちらの記事をご覧くださいPreRenderRegisterAsyncTask
  5. 独自のリクエスト タイムアウトを組み込みます。非同期 ASP.NET 要求は、同期 ASP.NET 要求に組み込まれている通常のタイムアウトを自動的に使用しません。次の 2 つのオプションがあります。
    • HttpRequest.TimedOutキャンセルトークンを使用します。
    • (WebForms/RegisterAsyncTaskのみ) 非同期タイムアウトを追加するにはPage.AsyncTimeoutasyncメソッドにCancellationToken.
于 2013-07-11T10:39:22.973 に答える
1

ToListAsyncを返しますTask。非同期としてマークPage_Loadすると、その中で await を使用できます。

大まかなルール: 何かが Task (メソッド名に「Async」を含む) を返す場合、それを待つ必要があります。

また、async/await を使用する場合は、使用する必要はありませんContinueWith。独自のメソッドを待ってWrite、次の行に呼び出しを配置し​​ます。

DumpEntities1 MyDumpEntities = new DumpEntities1();
var data = await MyDumpEntities.AgeGroups.ToListAsync();
var dataFromMyMethod = await MyasyncMethod()
Response.Write("f");
MyDumpEntities.Dispose();

Async="True"ページディレクティブに追加します

于 2013-07-11T07:23:43.203 に答える