讓我們考慮一個類(這不是我在應用程式中使用的類或代碼,只是想通過這個例子來學習)
class Person
{
public int Id {get; set;}
public string Name {get; set;}
public int DeptId {get; set;}
public string Department {get; set;}
}
現在讓我們假設我從我的資料庫中獲取了上述類的物件串列。如果數量很大,我想要一本包含部門 ID 和部門名稱的字典。Dictionary<int,string> 形式的東西。
我在類中有一個方法如下:
class Processing
{
private Task<Dictionary<int,string>> MapDepartments(List<Person> people) => Task.Run(()=> people.GroupBy(p=>p.DeptId).ToDictionary(group=> group.Key, group=>group.First().Department;
}
還有我班上的一個單獨的方法
class Processing
{
.
.
.
Task DoStuff()
{
.
.
.
//code execution to get data from the db
var departmentDictTask = MapDepartments(people);
.
.
.//some other code being executed, I don't need the department dictionary yet
.
.
var dictionaryData = await departmentDictTask.ConfigureAwait(false);
}
}
我的問題是:
- 這是我撰寫的從串列中創建字典的方法,它是異步運行的嗎?
- 我認為它確實如此,因為在除錯時,我看到它處于“運行”狀態一段時間,而我的其他代碼正在運行。雖然我不確定這是否確實如此。
- 這與將我的字典邏輯放在異步方法中有什么區別?
- 無論我實作了什么,這有點類似于擁有 .ToDictionaryAsync() 方法嗎?
uj5u.com熱心網友回復:
這是我撰寫的從串列中創建字典的方法,它是異步運行的嗎?
說它并行運行可能更準確。創建一個單獨的執行緒來產生結果。如果people沒有以執行緒安全的方式使用(例如,它是您在其他執行緒中添加的串列),那么您最終可能會遇到混亂的競爭條件。
當人們談論“異步”代碼時,他們可能意味著兩件事。
- 以不阻塞執行緒的方式對固有異步操作(如磁盤或網路 I/O)進行建模的代碼。
- 更廣泛地說,任何可以獨立于當前操作執行緒完成的操作。
你所做的符合第二個定義,但不是第一個。如果people由資料庫往返支持,您的代碼在呼叫完成時仍會阻塞執行緒:它只會阻塞與呼叫MapDepartments.
這與將我的字典邏輯放在異步方法中有什么區別?
由于您是從記憶體串列中提取的,并且您的所有操作都受 CPU 限制(不執行真正的異步操作),因此將您的邏輯放入一個async方法中沒有任何好處,因為該方法沒有任何東西可以await. 即使該方法會說它是async,它也會在回傳任務之前同步運行以完成。
假設創建該字典確實需要足夠的時間使其值得多執行緒處理,并且假設您沒有await在任務之前修改基礎串列,那么您當前的方法會更好。
無論我實作了什么,這有點類似于擁有 .ToDictionaryAsync() 方法嗎?
我的意思是,我想您可以撰寫一個ToDictionaryAsync僅在單獨的執行緒上執行的方法ToDictionary,但這確實不符合Async含義的精神。
當像 Entity Framework 這樣的庫提供一個ToDictionaryAsync()方法時,那是因為他們知道會有一個實際的異步資料庫呼叫,并且他們知道如何在不呼叫ToDictionary(). 我會保留ToDictionaryAsync這樣的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/480451.html
下一篇:如何找到分配給變數的物件的類?
