假设我有List
个用户,我想对所有用户执行某些操作,例如更新数据库中的某个属性。用户列表可能包含数十或数十万用户。如果要对用户完成的所有工作都是我的机器的本地工作,那么我只会使用Parallel.ForEach
来处理它们,但是因为这将涉及等待(可能很多秒)来调用外部服务完成后,我认为使用Task
s更合适。
现在,这是我的代码:
Task.WaitAll(usersList.Select(user => Task.Run(() => async
{
cancellationToken.ThrowIfCancellationRequested();
try
{
await UpdateUserInExternalService(user);
}
catch (Exception ex)
{
LogError($"Something went wrong with user 'user.Username'.", ex);
}
}, cancellationToken)).ToArray());
我有一些问题:
在我的测试中它似乎运作良好。我只是想确保没有任何我忽略的东西或者我可能会遇到的一些问题,或者是否有一个我没有遵循的最佳实践。
我愿意接受任何建议。提前谢谢。
根据评论,我无法控制外部服务或其数据库。我只有他们提供给我的电话,这需要一个用户。感谢。
答案 0 :(得分:4)
是的,此代码会立即启动所有操作。 Task.Run
做得不多。由于这是使用异步IO,因此线程池几乎没有参与。它不会限制它。
不要这样做。可能,这会使一些资源超载。使用https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/中的最后一段代码。这样的事情应该在框架中,因为几乎总是有必要为IO工作选择精确的并行度。
(3)在应用修复后无关紧要。在修复之前,令牌几乎没有任何影响,因为所有操作都立即启动,导致令牌仅立即被检查一次。之后不再可能取消。
您还可以将令牌传递给UpdateUserInExternalService
,以便立即取消。