簡體   English   中英

在async / await上阻塞主線程

[英]blocking main thread on async/await

我試圖讓我的基礎存儲庫類異步,我遇到了一些麻煩。 我在我的C#應用​​程序中使用Dapper ORM。

基本方法

protected async Task<List<T>> Read<T>(CommandDefinition cmd) {
    using(SqlConnection myCon = new SqlConnection(Config.DBConnection)) {
        await myCon.OpenAsync();

        IEnumerable<T> results = await myCon.QueryAsync<T>(cmd);

        List<T> retVal = results.ToList();

        myCon.Close();

        return retVal;
    }
}

通話方式

public List<Category> GetAllActiveCategories(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid).Result;
}

一切都看起來對我來說。 我有使用async關鍵字修飾的方法聲明。 我正在等待異步方法。

我遇到的問題是線程阻塞await myCon.OpenAsync(); 這是我第一次嘗試使用async和await,所以我確信我做錯了什么,但這並不明顯。 請幫忙!

發布的閱讀代碼很好。 問題出在消費代碼中。 如果在返回的Task上調用Wait()Result或在調用鏈中調用其先行Task ,則通常會遇到async死鎖。

在這些情況下,一般建議都適用: 不要阻止異步代碼 一旦開始使用async/await ,就應該在整個調用鏈中使用async/await

所以,你的調用方法就變成了

public Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}

... 要么

public async Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
    List<Category> result = await base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);

    // Do something.

    return result;
}

罪魁禍首是:

return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid).Result;

正如Kirill所指出的,無論.Result在任務中使用.Wait().Result ,都會同步阻塞。 你需要做的是:

public Task<List<Category>> GetAllActiveCategories(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}

這將把一個Task返回給這個方法的調用方法,依此類推......它必須是異步“一直向上”。

如果此代碼的頂級使用者是ASP.NET,那么你很好。 只需返回一個Task<IActionResult> (或包含在Task中的相應返回類型),框架將為您排序await

如果您正在編寫控制台應用程序或無法使其“一直異步”,則必須阻止.Result或使您的方法async void並使用await 遺憾的是,這兩個都不是一個很好的解決方案。 Async / await非常具有攻擊性,因為你真的必須在整個堆棧中使用它。

暫無
暫無

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

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