单个ASP.net请求的多个核心

pho*_*ait 8 c# asp.net iis

我正在尝试创建一个WebApi方法,该方法运行一系列难以进一步优化的循环计算.

x.Items.AsParallel().ForAll(item =>
{
    item.RunCalcs();
});
Run Code Online (Sandbox Code Playgroud)

当执行此代码时,通过查看服务器任务管理器,它似乎只会最大化单个处理器核心,同时保持其他核心不受影响.

根据我的阅读,asp.net将单个请求限制为一个处理器核心.由于这是一个总体请求很少的Intranet服务器,因此我不关心管理服务器资源.

有没有办法覆盖或解决这种行为,使我的循环运行得更快?

ipa*_*vlu 1

ASP.Net 甚至可以以非常巧妙的方式限制 TPL 所使用的线程数。只需创建一个仅限一个线程的 TaskScheduler,并在给定的 TaskScheduler 上启动 ASP.Net 请求即可。我敢打赌,他们会有一个有限的 TaskScheuler 池,这是有道理的......

那么当您调用 TPL 或 PLINQ 时,处理 ASP.Net 请求的任务内部会发生什么?

它使用调用 Task.Start 来调度任务,甚至更好,TPL 团队更喜欢使用 Task.Factory.StartNew 的方式。

但是,但是,但是:) ,这些是在TaskScheduler.Current之上的调度任务,这是我们已经在运行的有限 TaskScheduler!因此,无论您的机器有多少个核心,所有计划任务都将被烧录在有限的 TaskScheduler 上。

另一方面,似乎异步/等待操作正在使用.Net 4.5+中引入的新Task.Run(),并且有人建议,它是在TashScheduler.Default上调度任务,ThreadPool本身是什么,所以没有限制除了核心数量之外。除了这个线索之外,我没有证据:关于 Task.Start() 、 Task.Run() 和 Task.Factory.StartNew() TPL 的使用

不幸的是 AsParallel() 没有重载 TaskScheduler。

所以解决方案是:

  1. 第一个已经由 @SK 建议,使用类 Parallel 并指定并行度。该类早于 PLINQ,并使用 ThreadPool,因为它看起来很合适。
  2. 第二个想法是自己在 ThreadPool 上进行调度。
  3. 或者在 TaskScheduler.Default 上安排任务,以 ThreadPool 为目标。
  4. 或者为 ASP.Net 生成自己的线程(最糟糕的主意)。
  5. 或者使用 async/await 在 TaskScheduler.Default、ThreadPool 上运行工作,并在异步方法中使用 AsParalel(),因为 TaskScheduler.Current 与 TaskScheduler.Default 相同,只是 ThreadPool。

注意事项:请注意,在 ASP.Net 中的 ThreadPool 上调度繁重的内容可能会导致处理 ASP.Net 请求的性能下降...