WebAPI 中的线程(任务)限制(或一般情况下)
Threads (Tasks) Limit in WebAPI (or in general)
我们正在开发 WebAPI,它具有大约 200 个项目(可能更多)的一些解密逻辑。每次解密大约需要 20 毫秒。
我们已经尝试并行执行这些任务,所以我们会尽快完成它,但似乎我们遇到了某种限制,因为通过等待旧线程完成来重用线程(并且有只有少数人使用)- 整个动作大约需要 1-2 秒才能完成...
我们基本上想要实现的是让 x 个线程同时启动并在大约 20 毫秒后完成。
我们试过这个:
Await multiple async Task while setting max running task at a time
但这似乎只是描述了设置限制,而我们要释放它...
这是一个片段:
var tasks = new List<Task>();
foreach (var element in Elements)
{
var task = new Task(() =>
{
element.Value = Cipher.Decrypt((string)element.Value);
}
});
task.Start();
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
我们在这里缺少什么?
谢谢,
尼尔.
假设没有超线程:
如果1个项目耗时20ms,那么你可以看成是1核20ms。如果你想在 20 毫秒内完成 200 个项目,那么你需要 200 个核心。如果你没有那么多,那是做不到的...
在正常情况下,并行安排尽可能多的任务以优化您的系统
我不推荐 ASP.NET 上的并行性。它肯定会影响您的服务的可扩展性,尤其是当它面向 public 时。我想 "oh, I'm smart enough to do this" 几次并在 ASP.NET 应用程序中添加了并行性,但一周后不得不将其撕掉。
但是,如果您真的想要...
it seems we're getting some kind of a limit
是不是你机器上的物理内核限制?
We tried this: Await multiple async Task while setting max running task at a time
该解决方案专门针对异步并发代码(例如,I/O-bound)。您想要的是 parallel(线程)并发代码(例如,CPU-bound)。完全不同的用例和解决方案。
What are we missing here?
您当前的代码正在向线程池抛出大量并发任务,线程池将尝试尽可能地处理它们。您可以通过使用更高级别的抽象来提高效率,例如 Parallel
:
Parallel.ForEach(Elements, element =>
{
element.Value = Cipher.Decrypt((string)element.Value);
});
Parallel
在分区和(重新)使用线程(即不超过核心数)方面更加智能。所以你应该会看到一些加速。
但是,我希望它只是一个小的加速。您可能会受到物理内核数量的限制。
我们正在开发 WebAPI,它具有大约 200 个项目(可能更多)的一些解密逻辑。每次解密大约需要 20 毫秒。 我们已经尝试并行执行这些任务,所以我们会尽快完成它,但似乎我们遇到了某种限制,因为通过等待旧线程完成来重用线程(并且有只有少数人使用)- 整个动作大约需要 1-2 秒才能完成...
我们基本上想要实现的是让 x 个线程同时启动并在大约 20 毫秒后完成。
我们试过这个: Await multiple async Task while setting max running task at a time
但这似乎只是描述了设置限制,而我们要释放它...
这是一个片段:
var tasks = new List<Task>();
foreach (var element in Elements)
{
var task = new Task(() =>
{
element.Value = Cipher.Decrypt((string)element.Value);
}
});
task.Start();
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
我们在这里缺少什么?
谢谢, 尼尔.
假设没有超线程:
如果1个项目耗时20ms,那么你可以看成是1核20ms。如果你想在 20 毫秒内完成 200 个项目,那么你需要 200 个核心。如果你没有那么多,那是做不到的...
在正常情况下,并行安排尽可能多的任务以优化您的系统
我不推荐 ASP.NET 上的并行性。它肯定会影响您的服务的可扩展性,尤其是当它面向 public 时。我想 "oh, I'm smart enough to do this" 几次并在 ASP.NET 应用程序中添加了并行性,但一周后不得不将其撕掉。
但是,如果您真的想要...
it seems we're getting some kind of a limit
是不是你机器上的物理内核限制?
We tried this: Await multiple async Task while setting max running task at a time
该解决方案专门针对异步并发代码(例如,I/O-bound)。您想要的是 parallel(线程)并发代码(例如,CPU-bound)。完全不同的用例和解决方案。
What are we missing here?
您当前的代码正在向线程池抛出大量并发任务,线程池将尝试尽可能地处理它们。您可以通过使用更高级别的抽象来提高效率,例如 Parallel
:
Parallel.ForEach(Elements, element =>
{
element.Value = Cipher.Decrypt((string)element.Value);
});
Parallel
在分区和(重新)使用线程(即不超过核心数)方面更加智能。所以你应该会看到一些加速。
但是,我希望它只是一个小的加速。您可能会受到物理内核数量的限制。