簡體   English   中英

如何在 C# 中實現異步任務? 最佳實踐

[英]How to implement async tasks in c#? Best practice

我剛剛了解了有關異步等待的更多信息。 我曾經認為異步任務方法中的所有內容都只是在后台線程上執行。 現在我明白事實並非如此,並重構了我的一些代碼,因此它對我的 UIThread (WPF) 的阻塞更少。

這是我的“正常”異步方法:

public async Task<List<Data>> DoSomethingAsync(){
    var data = dbContext.Data.ToListAsync(); // <- Executes on a background thread internally
    ... // <- Executes on UIThread
    return dataList;
}

如果我現在在 ViewModel 中調用該方法,它實際上不會在后台執行。 為此,我必須調用Task.Run(DoSomethingAsync); .

我不想盲目地將所有對異步方法的調用都包裝到 Task.Run 中,所以我發現自己檢查了每個方法的實現,它是否具有“...”內容,或者只是從 ef core/http 包裝異步方法/文件系統。

這里的總體思路是什么? 默認情況下,所有的異步方法都應該像這樣嗎?

public Task<List<Data>> DoSomethingAsyncActuallyInBackground() {
    return Task.Run(() => {
        var data = dbContext.Data.ToListAsync();
        ... 
        return dataList;
    }
}

我覺得第一種方法不知何故“撒謊”。 它說 Async,但調用它我實際上不知道它是否是真正的異步/非阻塞代碼。 內部 ef 核心ToListAsync()在后台線程上工作,對嗎? 這就是它可能是非阻塞的。

我現在意識到我將“異步”等同於“在后台線程上/非阻塞”。 這是真的嗎?

我現在意識到我將“異步”等同於“在后台線程上/非阻塞”。 這是真的嗎?

異步確實意味着“非阻塞的”,而是“異步”(在這個詞的現代意義上的13759 async / await )“在后台線程”並不一定意味着。

我建議從我的async介紹開始,然后跟進There Is No Thread 考慮數據庫查詢的情況:一旦查詢被發送到數據庫服務器,線程就不需要只是坐在那里阻塞等待響應。 異步代碼釋放該線程來做其他事情,並使用Task<T> (又名“ promise ”)在查詢結果從數據庫服務器到達時通知應用程序。

暫無
暫無

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

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