C#等待web服务的线程CPU消耗

C#等待web服务的线程CPU消耗,c#,multithreading,task,task-parallel-library,cpu,C#,Multithreading,Task,Task Parallel Library,Cpu,我有一个web服务,我正试图缩短web请求的单个响应时间。 在对我的服务的单个请求的生命周期中,我有很多外部服务调用,我通过编写一个简单的图形库找到了解决方案 在图形上执行任务,该图形可以根据任务之间的依赖关系在外部配置为并行运行 我使用TPL在不同的线程上运行任务,我对等待有一些担心 (并将在图形执行时继续执行)线程 我读了一些关于非阻塞I/O工作原理的优秀文章,但我有一些缺点。 我知道,如果在执行请求的过程中没有主线程等待会更好,因为例如,如果我的线程池 100个线程和所有这些线程在某个时

我有一个web服务,我正试图缩短web请求的单个响应时间。 在对我的服务的单个请求的生命周期中,我有很多外部服务调用,我通过编写一个简单的图形库找到了解决方案 在图形上执行任务,该图形可以根据任务之间的依赖关系在外部配置为并行运行

我使用TPL在不同的线程上运行任务,我对等待有一些担心 (并将在图形执行时继续执行)线程

我读了一些关于非阻塞I/O工作原理的优秀文章,但我有一些缺点。 我知道,如果在执行请求的过程中没有主线程等待会更好,因为例如,如果我的线程池 100个线程和所有这些线程在某个时间点使用,这是一个失败,我的服务无法响应下一个请求。这是不可伸缩的

我可以增加线程池的线程数,我可以完成这个失败,但正如我所读到的,有更多的线程 可能会导致更多的内存使用(每个线程都有自己的堆栈,例如,在这一点上我没有问题,我有足够的内存) 以及更多的CPU消耗(上下文切换?)。这是我一点也不明白的

我知道CPU不会为处于等待状态的线程花费空闲时间。 所以我认为我的主线程在这一点上不会消耗CPU

所以我的问题是我的设计有什么不好的地方?如果等待线程不消耗CPU, 让更多的线程处于CPU的等待状态有什么不对

如果交换机的状态变为“ready to execute”,内核会在交换机上检查这些线程?如果是,这是真的吗 我应该处理的一件大事?如果不是,你能给我解释一下CPU的等待线程少的优点吗

我最满意的答案之一就是这里; 说:

CPU是根据线程活动和 请求的线程数(请记住,一个线程也会消耗内核 因此,资源必须在内核级别进行管理,因此 必须处理的线程越多,必须消耗的内核时间就越多 管理它们)


但我也不明白这部分。请你解释一下,就像我不太了解内核或cpu如何处理线程一样。

在大多数(99%的操作系统)操作系统中,睡眠期间的线程不会消耗cpu,因此有很多线程只会消耗内存,但每次发信号时(准备好数据的I/O),内核都需要重新加载它(堆栈、堆、内存…)这会消耗CPU,因此通过创建线程,您正试图通过让内核为您执行任务来解决排队问题。@rastbin问题是,您如何知道是否有足够的可用线程?过度配置线程将导致内存使用高峰。如果交通突然激增,会发生什么?您的站点将崩溃。此外,如果线程池确定线程未被使用,即在低流量下,它将开始减少线程数。通过阻塞IO和手动增加线程,您只会给自己造成一大堆伤害。我强烈建议您不要这样做。@rastbin您可以使用async await并发调用多个异步IO,您不需要使用
并行
或启动新的阻塞线程。您只关注一个问题,确保可以使用更多线程并等待它们。但随着线程的增加,将有更多的时间花在上下文切换上,所以您将开始减少那里的CPU周期。此外,由于主线程正在等待,因此无法为新客户端提供服务。这让我想到了被送达的请求数量。基本上,拥有更多线程并不是一个好的体系结构,因为它不能很好地扩展。在使用所有线程之前,您需要确保您需要所有线程,如果由于等待线程而需要大量线程,那么这将导致浪费。此外,使用这种架构,您的解决方案可能会比异步方法更加复杂。在大多数(99%的操作系统)操作系统中,睡眠期间的线程不会消耗CPU,因此拥有大量线程只会消耗内存,但每次发出线程信号(数据就绪I/O)时,内核都需要将其加载回(堆栈、堆、内存..)这会消耗CPU,因此通过创建线程,您正试图通过让内核为您执行任务来解决排队问题。@rastbin问题是,您如何知道是否有足够的可用线程?过度配置线程将导致内存使用高峰。如果流量突然激增,会发生什么情况?您的站点将我会失败。此外,如果线程池确定线程未被使用,即在低流量下,它将开始减少线程数。通过阻塞IO和手动增加线程,您只会使自己受到一大堆伤害。我强烈建议您不要这样做。@rastbin您可以同时调用多个异步IO u使用async await,您不需要使用
并行
或启动新的阻塞线程。您只需要关注一个问题,当然可以使用更多线程并等待它们。但是随着线程的增加,将在上下文切换上花费更多的时间,因此您将开始减少那里的CPU周期。此外,由于主线程正在等待,因此无法停止服务新客户端。这让我想到了服务请求的数量。基本上,拥有更多的线程数量并不是一个好的架构,因为它不能很好地扩展。在使用所有线程之前,你需要确保你需要所有的线程,如果因为你在等待它们而需要很多线程,那么这就意味着浪费。同样,在使用这些线程之前,你需要确保你需要所有的线程架构的可能性是,与异步方法相比,您的解决方案可能会变得更加复杂。