EntityFramework(6)和async(waitingForActivation)?

.net-4.5 async-await c# entity-framework entity-framework-6

我已經下載了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簽名 在此處輸入圖像描述

我錯過了什麼?

一般承認的答案

基於你的評論和你遇到的問題:

var data = MyDumpEntities.AgeGroups.ToListAsync();

data類型是什麼? Task<List<AgeGroup>> 。這是對的,而不是List<AgeGroup> 。因此,您必須將Page_Load標記為異步(如果可能):

var data = MyDumpEntities.AgeGroups.ToListAsync();

或者以某種方式等待執行(繼續,阻塞等待)。

另一件事(如果我錯了,其他人可能想要糾正),但由於你正在使用第二次調用的繼續,我會非常小心處理繼續之外的上下文。事實證明,你可以先發製人。在這種特殊情況下,你沒有在延續中使用上下文,但它看起來很可疑......

所以我要么

var data = MyDumpEntities.AgeGroups.ToListAsync();

或者也只是在那裡使用async

var data = MyDumpEntities.AgeGroups.ToListAsync();

並在頁面指令中添加Async="True"


熱門答案

其他人已經指出正確的解決方案是使用await ,但我沒有看到為什麼這麼好的解釋。

原始代碼錯誤有兩個原因。首先,您使用ContinueWith而不捕獲ASP.NET應用程序中的上下文,因此continuation( Response.Write調用)沒有請求上下文,因此沒有寫入的響應。

await通過在await之前捕獲上下文並使用它來恢復方法的其餘部分來為您處理這個問題;在這種情況下,它將捕獲表示當前請求/響應的AspNetSynchronizationContext

另一個原因是異步代碼將同時運行。因此, MyasyncMethod將開始執行,到達await ,並將未完成的任務返回給Page_Load 。然後, Page_Load繼續執行該任務並繼續執行 ,處理上下文。因此,當ToListAsync請求仍在運行時,可以處理上下文。

await還為您解決了這個問題,因為它將“暫停” Page_Load方法,直到MyasyncMethod完成。

最後,在ASP.NET中使用async時,還應考慮以下幾點:

  1. 您必須以.NET 4.5為目標。不要使用Microsoft.Bcl.Async
  2. 您必須將targetFramework設置為4.5, UseTaskFriendlySynchronizationContext設置為true。
  3. (僅限WebForms)將Page.Async設置為true。
  4. 考慮使用RegisterAsyncTask而不是await 。我通常更喜歡await因為不同的方法有更多的關注點分離,但ASP.NET團隊更喜歡RegisterAsyncTask因為在PreRender之後有一個“同步”點,運行時等待所有操作完成。 有關如何使用RegisterAsyncTask請參閱此文章。
  5. 構建自己的請求超時。異步ASP.NET請求不會自動使用內置於同步ASP.NET請求的正常超時。有兩種選擇:
    • 使用HttpRequest.TimedOut取消令牌。
    • (僅限WebForms / RegisterAsyncTask )您可以通過設置Page.AsyncTimeout並讓async方法採用CancellationToken來添加異步超時。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因