【发布时间】:2020-09-28 19:38:21
【问题描述】:
我得到了下面这段暂定的代码,它应该生成一个要同时执行的任务列表。 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 而不是继续执行其他 2 个异步调用时,它会跳回到代码的开头
SyncAction<IUmbracoActiveCampaignEntity> syncActionResult; 并且虽然所有代码都“正常”运行,但 var result = await Task.WhenAll(syncActionTasks); 行返回了正确数量的 contactDto 对象,但这些对象本身重复出现,并且不像预期的那样唯一。
任何线索,为什么以及什么可以调整以获得预期的结果?任何方向和建议将不胜感激。
【问题讨论】:
-
您确定
contactDto、Mapper和this.Contacts对象是线程安全的吗?希望它们是,因为它们将在没有同步的情况下被多个线程同时访问。还有变量syncActions与其余代码有什么关系?
标签: c# asp.net-web-api async-await task-parallel-library