我從未嘗試使用WaitAll()或WhenAll()運行async功能時。在查看了許多檔案、SO 帖子和教程后,我還沒有找到足夠的資訊,所以我在這里。
我正在嘗試找出執行以下操作的最佳/正確方法:
使用 EF6,獲取資料為List<Entity>. 遍歷每個Entity并呼叫外部 API 以執行某些操作。外部 API 回傳Entity我需要存盤在同一個Entity.
目前我已經構建(未測驗)以下(沒有錯誤處理代碼):
public IEnumerable<Entity> Process() {
bool hasChanged = false;
var data = _db.Entity.Where(x => !x.IsRegistered);
foreach (var entity in data) {
var result = await CallExternalApi(entity.Id, entity.Name);
entity.RegistrationId = result.RegistrationId;
entity.IsRegistered = true;
_db.Entry(entity).State = EntityState.Modified;
hasChanges = true;
}
if (hasChanges) {
uow.Commit();
}
return data;
}
我覺得我可以利用async.
任何指導都非常感謝。
更新
我正在呼叫的 API 是用于添加注冊人的 Zoom Api。雖然他們確實有批量添加注冊人的方法,但它不會回傳我需要的 RegistrantId 和 Join Url。
uj5u.com熱心網友回復:
首先,弄清楚您的外部 API 是否可以批量獲取您想要的所有專案。如果是這樣,請使用它而不是發送一大堆請求。
如果您需要為每個專案發送單獨的請求,但希望同時進行,您可以這樣做:
public async Task<IReadOnlyCollection<Entity>> Process() {
var data = _db.Entity.Where(x => !x.IsRegistered).ToList();
if(!data.Any()) { return data; }
var entityResultTasks = data
.Select(async entity => new { entity, result = await CallExternalApi(entity.Id, entity.Name) })
.ToList();
var entityResults = await Task.WhenAll(entityResultTasks);
foreach (var entityResult in entityResults) {
var entity = entityResult.entity;
var result = entityResult.result;
entity.RegistrationId = result.RegistrationId;
entity.IsRegistered = true;
_db.Entry(entity).State = EntityState.Modified;
}
uow.Commit();
return data;
}
您需要注意目標源上可能的并發限制。考慮使用Chunk將您的作業分成可接受大小的批次,或者利用信號量或其他東西來限制您撥打的電話數量。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360683.html
上一篇:用于異步計算/獲取的PythonAsyncio/Trio
下一篇:await在異步函式之外使用
