2016-03-07 145 views
0

我試圖製作一個異步方法,我可以多次調用並稍後等待 - 該方法應該調用數據庫,等待結果,一旦有結果,然後返回最終結果。它看起來像這樣:包含異步調用和同步操作對結果的異步方法

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer() 
{ 
     //stuff is just an Entity Framework database call 
     var stuff = await myEfDbContext.StuffTable.ToListAsync();      
     long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count(); 
     return itemsCount; 
} 

這似乎是一個明顯的失誤,因爲我指定的返回類型的任務,而我其實只返回一個長。這將編譯,而是拋出異常:

類型的第一次機會異常的「System.NotSupportedException」 發生在EntityFramework.dll

我打算使用此代碼如下所示:

Task<long> myAsyncCall = GetSomethingFromDbAndSelectSomethingOnServer(); 
long myCount = await myAsyncCall; 

這可能是一個有點文不對題,但闡述,這裏有一些很好的的作品:

Task<long> pendingItemCountCall = _mongoItems.Find(filter).CountAsync(); 
long myCount2 = await pendingItemCountCall; 

當然,不同之處在於它只是對db的異步調用,而沒有進一步的操作,我正在嘗試在我正在問的問題的SQL調用中做什麼。

編輯:

所以,實際上,這似乎是有問題的行:

var stuff = await myEfDbContext.StuffTable.ToListAsync(); 

如果我評論了這一點,並手動設置計數VAR,代碼去。我很困惑,但我更關心整體問題 - 我是否在這裏正確使用異步,不一定是我的特定錯誤的錯誤。

+0

@HenkHolterman:它的工作! – VSO

回答

3

您無法在同一個上下文中等待多個查詢。你必須爲每個操作使用自己的上下文:

public async Task<long> GetSomethingFromDbAndSelectSomethingOnServer() 
{ 
     using(var context = new MyEfDbContext()) 
     { 
      // include the following if you do not need lazy loading and want some more speed 
      context.Configuration.AutoDetectChangesEnabled = false; 
      context.Configuration.ProxyCreationEnabled = false; 

      var stuff = await myEfDbContext.StuffTable.ToListAsync();      
      long itemsCount = stuff.Where(someQueryThatCantGoToDb).Count(); 
      return itemsCount; 
     } 
} 
+0

感謝您的答案,我在這裏看到:http://stackoverflow.com/questions/20946677/ef-data-context-async-await-multithreading,我會檢查並接受答案,如果它的工作,雖然那裏似乎是一些ifs和buts。 – VSO

+1

答案是2歲。從今天起,EF和ASP都可以正常工作。對於ASP,您只需知道在ConfigureAwait(false)後您將失去HttpContext.Current,因此如果您需要HttpContext.Current,則不得使用ConfigureAwait(false)。 – wertzui

+0

在使用實體框架(使用實體框架)封裝後,它仍然失敗,但我會繼續尋找。鼓勵聽到它應該工作,將繼續與它混亂。我確實認爲這是問題,因爲它只在一次調用時才起作用,並且在多次調用時僅在後續迭代中失敗。 – VSO