1

我已經下載EF6(爲了使用asyncEntityFramework(6)和異步(waitingForActivation)?

所以我寫了這個簡單的方法:

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我看到這個:

enter image description here

PS這是ToListAsync簽名 enter image description here

我在想什麼?

+0

你不'await'ing這個電話,你應該去'VAR數據=等待MyDumpEntities.AgeGroups.ToListAsync();'... –

+0

他不是等待呼叫對MyasyncMethod()的調用返回任務? – CodingIntrigue

+0

@PatrykĆwieknoope http://i.stack.imgur.com/WqdZb.png –

回答

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(); 
    }  
} 

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

另一件事(別人可能想糾正,如果我錯了),但由於你使用第二次調用的延續,我會非常小心地處理延續以外的上下文。它可能會證明您先發制人地處理上下文。在這種特殊情況下,你不使用在延續的背景下,但看起來可疑......

所以我要麼

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

或者只是使用async有太多

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

並將Async="True"添加到頁面指令

+0

我認爲如果'MyasyncMethod'已經被標記爲異步,我不需要在'page_load'中也這麼做...... ........無賴 –

+0

@RoyiNamir那麼,如果你想使用'await'方法,該特定方法必須標記爲「async」。當然,這是一個好主意,即使在輔助方法中,「一路下降」也是如此...... –

+0

「一路下跌」 - 說得好。不知道我應該這樣做。 –

1

ToListAsync返回一個Task。將Page_Load標記爲async,那麼您可以使用await。粗糙的規則:如果某個東西返回一個Task(方法名中包含「Async」),則必須等待它。

此外,使用異步/等待時,您不必使用ContinueWith。只需等待您自己的方法,並將Write呼叫置於下一行。

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

,並添加Async="True"到頁面指令

+0

謝謝你的回答。 –

2

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

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

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

另一個原因是異步代碼將同時運行。因此,MyasyncMethod將開始執行,達到其await,並將未完成的任務返回到Page_LoadPage_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之後有一個「同步」點,運行時等待所有操作完成。 See this article for how to use RegisterAsyncTask.
  5. 構建您自己的請求超時。異步ASP.NET請求不會自動使用內置於同步ASP.NET請求的正常超時。有兩種選擇:
    • 使用HttpRequest.TimedOut取消令牌。
    • (僅適用於WebForms/RegisterAsyncTask)您可以通過設置Page.AsyncTimeout並使您的async方法採用CancellationToken來添加異步超時。
+1

我認爲這篇文章有一個遺漏的異步。 http://i.stack.imgur.com/P3mnN.png(我的情況在這裏) –