C#跨不同会话的线程工作平衡

C#跨不同会话的线程工作平衡,c#,multithreading,C#,Multithreading,假设您有一个web服务器接收请求。现在,每个请求都连接到一个用户会话。现在,请求中执行的代码是异步的,并使用多线程并行执行,例如使用Task.Run()、async wait或parallel.ForEach 现在可以观察到的是,对于某个会话,会触发一个比其他会话更重的请求,使用更多的并行任务。因此,对于操作繁重的请求,单个会话几乎可以让所有线程执行其任务。通过捕获更多任务,其他会话请求的速度会减慢。对于某些会话,服务器看起来相当快(那些首先获得线程的会话),而对于其他会话,服务器看起来相当慢,

假设您有一个web服务器接收请求。现在,每个请求都连接到一个用户会话。现在,请求中执行的代码是异步的,并使用多线程并行执行,例如使用
Task.Run()
async wait
parallel.ForEach

现在可以观察到的是,对于某个会话,会触发一个比其他会话更重的请求,使用更多的并行任务。因此,对于操作繁重的请求,单个会话几乎可以让所有线程执行其任务。通过捕获更多任务,其他会话请求的速度会减慢。对于某些会话,服务器看起来相当快(那些首先获得线程的会话),而对于其他会话,服务器看起来相当慢,在最坏的情况下甚至没有响应。我想要的是一些平衡,这样给会话分配的线程数量就可以均匀分布

如何解决这个问题

我认为这是有意义的选择。请确认或告诉我您不同意的原因:

  • 在操作排队的专用线程中完成繁重的任务
  • 使用自定义

最有可能的是,我没有想到还有更多的选择。请帮我找到这个问题的正确措辞。如果您能指导我找到解决方案(从概念上解决或避免问题),我也会非常高兴。

另一种选择是对每个会话提交的任务使用优先级。每个会话可以有一个优先级值,在会话开始时,提交的任务优先级较高,从会话提交的任务越多,优先级越低。这样,如果会话提交大量任务,新会话可以有执行时间来执行其启动任务,因为它将具有更高的优先级。(*)

尽管这种方法不能处理从会话提交的开始任务是需要大量时间的繁重任务的情况。(与第一个选项一样,如果可以检测到长时间运行的任务,则可以降低优先级)

MSFT提供了QueuedTaskScheduler实现,您应该检查它。 及

(*)该方法的另一个变化是:;每个优先级都可以有自己的线程池,优先级较高的线程池可以包含比优先级较低的线程更多的线程。

两个可能的选项:

1) 创建机器分离,以便长时间运行的任务运行在单独的机器上,并且可以与接收请求和响应请求的web服务器分开扩展


2) 进程亲缘关系。重写长时间运行的方法,以相同的线程ID为目标,等待时间较长。例如如果你有一台双核机器。仅为长时间运行的任务分配cpu 2,以便在cpu 1上仍可处理正常请求。这将很难做到,但在不扩展到新机器的情况下也会起作用

你能把你的问题具体点吗?什么是请求?它是否类似于web请求(简短、快速完成等)?什么是会议?请求和会话之间的关系是什么?您是否使用内置的线程池来存储线程?工作的性质是什么(CPU限制、IO限制?每个工作单元完成和释放线程所需的时间有很大差异吗?是什么让一个请求/会话比其他请求/会话更重?有没有一种方法可以提前识别那些繁重的会话?让我们假设一个简单的web请求,其中一些具有繁重的操作。操作主要受CPU限制。一个请求可能更重,这意味着该请求中的操作具有更高的并行度,因此只需使用更多线程。其他操作正在等待线程变为空闲线程,或者对其余线程执行较慢的操作。从理论上讲,识别重线程是可能的。web服务器上许多CPU占用量大的线程是很难克服的。请记住,运行CPU绑定工作的4核机器在一次只运行4个线程时运行得最好。如果只有部分工作是CPU受限的,您可能希望将工作分派到单独的服务器,或者分派到仅在一个或几个专用内核上工作的单独线程池。很抱歉它依赖于下一个问题:如何在stackoverflow上提出不在模式“此代码不工作,为什么?”中的概念性问题?或者有没有其他地方我应该问这样的问题,我甚至还不知道如何表达这个问题。我试图把范围限制在只问正确的术语来描述这个问题