[英]Difference in output between these two simple implementations of Async and Await
[英]Difference between these two async implementations
我正在使用EF的異步方法從數據庫中獲取數據。 大部分時間都很好。 我最近遇到了一些ObjectContextDisposed異常,我很好奇為什么我的解決方案有效:
這是我拋出ObjectContextDisposed
原始代碼:
public Task<List<string>> GetEventParameterMru(EventParameter parameter, int count = 20)
{
using (var repo = new ConfigurationRepository())
{
return repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count)
}
}
這是我的新代碼,不拋出:
public async Task<List<string>> GetEventParameterMru(EventParameter parameter, int count = 20)
{
using (var repo = new ConfigurationRepository())
{
var result = await repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count);
return result;
}
}
有人可以向我解釋有什么不同,為什么它有效?
僅供參考,在我使用此方法的所有用法中,我調用await GetEventParameterMru()
謝謝
GetEventParameterMRU
顯然是一個啟動Task
來檢索某些數據的方法。 因此, GetEventParameterMRU
在repo
上的所有操作完成之前返回。
兩個版本的代碼都使用using
語句,該語句被轉換為try/finally
塊。 在finally
塊中, repo
將被處置 。
在您的第一個版本中,您在調用GetEventParameterMRU
(啟動任務)后立即返回。 這意味着當使用repo
的Task
仍在運行時, repo
立即處理。 因此,當此Task
訪問repo
您將收到您的repo
的ObjectDisposedException
在第二個版本中,您使用await
。 因此,編譯器將您的整個方法轉換為狀態機 。 該方法在await
語句中將控制權返回給其調用者,但不傳遞finally
塊。
當Task
完成時,在await
語句之后繼續執行您的方法。
所以repo
只在Task
完成時處理 。 所以你沒有得到ObjectDisposedException
。
以下是我對初始代碼審查的理解:
在第一個,它不是Async
實現,但仍然從using block
返回一個Task,最后Task is executed
時調用repo.Dispose()
(假設它由調用者完成,但仍然保持為真對於方法 - GetEventParameterMRU
啟動它,在那個時間處置repo是非常可行的,但仍然是操作,因此異常
在第二個中,情況並非如此,即使它已經釋放了UI /調用線程,直到並且除非完成:
await repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count)
它不會調用repo.Dispose()
,因此完全避免了ObjectContextDisposed
問題
讓我為你翻譯一下:
第一:
Create repository
Start GetEventParameterMRU on repository as Task
Dispose repository
return Task, that is still working with repository
第二個:
Create repository
Start GetEventParameterMRU on repository as Task
Wait for Task to finish to get result
Dispose repository
return result
如您所見,這里的問題非常清楚。
我相信這與第一個沒有顯式捕獲當前SynchronizationContext的代碼有關,而等待DOES顯式捕獲它。
進一步閱讀:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.