我在下面获得了这条暂定的代码,它应该生成要同时执行的任务列表。 try ... catch ...中的代码表示每个任务。但是代码块本身包含3个异步调用,这些调用应顺序执行,基本上第二个调用取决于第一个,第二个依赖于第二个。
var syncActions = new List<SyncAction<ContactDto>>();
ContactDto contactDto = null;
var syncActionTasks = updatedNodes.Select(async node =>
{
SyncAction<IUmbracoActiveCampaignEntity> syncActionResult;
contactDto = Mapper.Map<ContactDto>(node);
try
{
var firstAsyncCallResult = await this.Contacts.GetByEmailAsync<ContactsRoot>(contactDto.Email);
...(code omittted for brevity)...
var secondAsyncCallResult = await this.Contacts.AddOrUpdateAsync(firstAsyncCallResult);
...(code omittted for brevity)...
var thirdAsyncCallResult = await this.Contacts.GetAccountContactAssociation(secondAsyncCallResult);
}
catch (ActiveCampaignException ex)
{
// handle error
}
return Task.FromResult(contactDto);
})
.ToList();
var result = await Task.WhenAll(syncActionTasks);
...(code omittted for brevity)...
[我的经验是,当代码执行firstAsyncCallResult
而不是继续进行另外两个异步调用时,它会跳回到代码的开头SyncAction<IUmbracoActiveCampaignEntity> syncActionResult;
,尽管所有代码都“运行”良好,但var result = await Task.WhenAll(syncActionTasks);
行返回了正确数量的contactDto
对象,但是这些对象本身反复出现,并且不符合预期。
任何线索,为什么以及可以进行什么调整才能获得理想的结果?任何方向和建议将不胜感激。
[我的经验是,当代码执行firstAsyncCallResult而不是继续进行另外两个异步调用时,它会跳回到代码
SyncAction<IUmbracoActiveCampaignEntity> syncActionResult;
的开头
是,一旦第一个await
被击中,从Lambda返回一个Task
,下一个迭代将开始。 Task
完成后,该方法将恢复。
也Task.FromResult
不应在异步方法中使用;异步方法隐式返回一个Task
,因此您无需自己创建一个。立即返回DTO:
return contactDto;
对ToList()
的调用也是多余的,因为Task.WhenAll
接受了已经从您的IEnumerable<Task<TResult>>
返回的Select
。