繁体   English   中英

在C#中启动数千个任务的最佳方法是什么?

[英]What is the best way to start thousands of Tasks in C#

假设我有一个用户List ,我想对所有用户执行一些操作,例如更新数据库中的一个属性。 用户列表可能包含数十或数十万用户。 如果要对用户完成的所有工作都是我的机器的本地工作,那么我只会使用Parallel.ForEach来处理它们,但是因为这将涉及等待(可能是几秒钟)来完成对外部服务的调用,我认为使用Task更合适。

现在,这是我的代码:

        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());

我有一些问题:

  1. 如果列表中有10,000个用户,它是否实际上同时创建了10,000个任务(巨大的内存峰值)? 或者它只是创造,比方说10,然后当一些任务完成时其他任务被旋转起来?
  2. 我是如何使用取消令牌看起来正确的?
  3. 如果我在调用它之后立即取消操作,它是否仍然需要在取消之前启动所有10,000个任务,或者是否因为我将取消令牌传递给Task.Run参数而避免了?

在我的测试中它似乎运作良好。 我只是想确保没有任何我忽略的东西或者我可能会遇到的一些问题,或者是否有一个我没有遵循的最佳实践。

我愿意接受任何建议。 提前致谢。

更新

根据评论,我无法控制外部服务或其数据库。 我只有他们提供给我的电话,这需要一个用户。 谢谢。

是的,此代码将立即启动所有操作。 Task.Run做得不多。 由于这是使用异步IO,因此线程池几乎没有参与。 它不会限制它。

不要这样做。 可能,这会使一些资源超载。 使用https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/中的最后一段代码。 这样的事情应该在框架中,因为几乎总是有必要为IO工作选择精确的并行度。

(3)修复后无关紧要。 在修复之前,令牌几乎没有任何影响,因为所有操作都立即启动,导致令牌仅立即被检查一次。 之后取消不再可能。

您还可以将令牌传递给UpdateUserInExternalService以实现更快速的取消。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM