簡體   English   中英

這兩個異步實現之間的區別

[英]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來檢索某些數據的方法。 因此, GetEventParameterMRUrepo上的所有操作完成之前返回。

兩個版本的代碼都使用using語句,該語句被轉換為try/finally塊。 finally塊中, repo將被處置

在您的第一個版本中,您在調用GetEventParameterMRU (啟動任務)后立即返回。 這意味着當使用repoTask仍在運行時, 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顯式捕獲它。

進一步閱讀:

https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM