net多线程

一、异步编程

使用await不要用Result

async/await主要用于创建异步方法,防止阻塞当前线程。

当一个线程遇到await时,会在await修饰的逻辑启用新线程(执行异步逻辑)时,直接释放本线程,使用新线程去执行该语句和后续语句。即不阻塞当前线程,只占用1个线程。

例如:

Task.Run(async () =>
{
  var result = await Task.Run(() => { Thread.Sleep(3000);
            return "qaz"; }); });

代码是在线程里await执行一个异步方法。

断点打在

return "qaz";

处,调试如下

  

可以看出除了主线程外,只有一个工作线程。即外层的线程直接被释放。

当用Result属性时,线程会被阻塞等待,而不是释放

Task.Run(async () =>
            {var result =  Task.Run(() =>
                {
                    Thread.Sleep(3000);return "qaz";
                }).Result;
            });

有个托管ID=3的线程在等待,它就是外层线程,导致占用了2个线程

 二、线程池

最小线程池个数是CPU的核心数,最大线程池个数是32767dotnet 生成新线程的规则是,当有新任务需要线程时,先在线程池中找空闲线程,如果没有空闲,就等待500ms看是否有线程空闲出来,如果还是没有,产生一个新线程。

比如4核服务器的线程数就是4

ThreadPool.ThreadCount: 4, Minimum work threads: 4, Minimum completion port threads: 4

而这点线程对高并发应用来说都不够塞牙缝。虽然 ASP.NET Core runtime 会在线程不够用时自动创建线程,但是每秒只能创建1-2个线程,线程数增加也很慢,导致很多请求被拒绝。

后来想通过将线程池的最小线程数调大去解决问题,但是设置1k以上时,SetMinThreads返回值为false,设置不生效。
需用SetMaxThreads先设置最大线程数,之后再SetMinThreads设置最小线程数。奇迹这样发生了……
而且更诡异的是SetMaxThreads设置一个比以前小的值,之后再调用SetMinThreads设置最小线程数也是OK的。

设置OK之后程序虽然程序的线程数并不会立马增加,但是一旦遇到高并发请求,线程数增加是非常快速的。差不多1秒几十个线程左右。当并发量降低之后,线程数也会降低。但是当并发再次增高的时候,线程数的增加会比之前更快(一两秒就能恢复到2k水平)

原文地址:https://www.cnblogs.com/dengquan/p/14309252.html