ManagedThreadId如何对应C#中的线程和CPU上的线程?

ManagedThreadId如何对应C#中的线程和CPU上的线程?,c#,multithreading,C#,Multithreading,我试图弄清楚C是如何管理线程的 我刚刚启动了一个新的webapi项目。我将它打包到新的线程中: public class Program { public static

我试图弄清楚
C
是如何管理线程的

我刚刚启动了一个新的
webapi
项目。我将它打包到新的
线程中

public class Program                                                                       
{                                                                                          
    public static void Main(string[] args)                                                 
    {                                                                                      
        var thread = new Thread(() => CreateHostBuilder(args).Build().Run());              
        thread.Start();                                                                    
    }                                                                                      
                                                                                           
    public static IHostBuilder CreateHostBuilder(string[] args) =>                         
        Host.CreateDefaultBuilder(args)                                                    
            // DEFAULT STARTUP HERE
            .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); 
}          
公共类程序
{                                                                                          
公共静态void Main(字符串[]args)
{                                                                                      
var thread=新线程(()=>CreateHostBuilder(args.Build().Run());
thread.Start();
}                                                                                      
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
//此处默认启动
.ConfigureWebHostDefaults(webBuilder=>{webBuilder.UseStartup();});
}          
我向其中添加了我的自定义控制器:

[ApiController]                                      
[Route("[controller]")]                              
public class ValueController : ControllerBase        
{                                                    
    [HttpGet("fast")]                                
    public async Task<ActionResult<int[]>> Fast()    
    {                                                
        var task = new Task<int[]>(() =>             
        {                                            
            return new[] {1, 2, 3};                  
        });                                          
        task.Start();                                
                                                     
                                                     
        return Ok(await task);                       
    }                                                
                                                     
    [HttpGet("infinite")]                            
    public async Task<ActionResult<int[]>> Infinite()
    {                                                
        var task = new Task<int>(() =>               
        {                                            
            while (true)                             
            {                                        
            }                                        
                                                     
            return 0;                                
        });                                          
        task.Start();                                
                                                     
        return Ok(await task);                       
                                                     
    }                                                
}                                                    
[ApiController]
[路线(“[控制器]”)]
公共类ValueController:ControllerBase
{                                                    
[HttpGet(“快速”)]
公共异步任务

第二:

整个
ASP.NET
应用程序与编号为
@13272
的应用程序在同一线程上工作


我的问题是,
.NET
如何在一个线程中管理
任务
,当后台有无限多个任务运行时,可以运行多个任务?

在一个操作系统线程上运行多个用户模式线程的概念被称为或可能是。绿色线程不被.NET使用。虽然可以使用光纤,但它可以是罕见的,大多数被认为是过时的,在这种情况下不相关

在.Net中,每个正在运行的任务都由一个托管线程运行,该线程由一个OS线程支持。但是,调用
task.Start()
并不意味着该任务正在运行,它只会将该任务标记为挂起,即在有可用资源时可供运行

完全有可能在任务启动之前完成查询,并为任务重用同一线程


在您的示例中,还需要考虑Web服务器组件。我对asp.Net不是很熟悉,但我希望挂起的查询最终会在运行时终止。

以下是运行程序时发生的情况

  • O/S加载.exe映像并定位其
    main
    入口点。这是一个非托管端点,作为c#程序员,您永远看不到它

  • main
    入口点执行.NET引导程序;加载.NET运行时,验证.exe,加载相关程序集,建立堆和垃圾收集线程以及线程池。然后在c#应用程序中调用
    main
    入口点

  • Main
    方法创建另一个线程,启动它,并将控制权返回给引导程序。此时,您的程序差不多完成了

  • 您启动的线程不是后台线程,因此它是

  • 线程调用
    IHost
    Run
    扩展方法

  • 运行应用程序并阻止调用线程,直到主机关闭

    由于线程被阻塞,它将继续存在,直到主机关闭。这就是您获得
    @13272
    线程的地方

    我不太了解这里的内部结构,但我怀疑这就是您的
    IHost
    最终要做的:

  • 向O/S注册TCP/IP侦听器,例如建立回调
  • 当流量到达时,O/S调用回调
  • 回调由主机处理,主机实例化控制器并异步调用action方法
  • 在操作方法“returns”(操作方法要么已完成,要么使用
    wait
    来产生控制)之后,它检查任务是否已完成。如果未完成,则将继续执行的任务放在线程池中,在适当的时候执行

  • 主机所做的所有事情都可能发生在任何线程上,这就是那些ID不断变化的原因。

    我不确定我要看的是什么(图像试图显示什么)你想知道什么信息。你可能会发现这些问题很有趣:
    整个ASP.NET应用程序都在同一个线程上运行,而@13272的线程是错误的。
    可能是*主线程,但每个请求都由一个单独的工作线程处理。否则就不可能处理1000个并发请求@Evk我没有说一个新线程,我说的是来自线程池的另一个线程
    。我重复了
    threadpool
    三次自从.NET Framework 2.0以来,CRL主机可以使用光纤,SQL Server做到了()。因此,Microsoft在大多数版本中将
    AppDomain.GetCurrentThreadId
    标记为过时().NET还可以回收托管线程ID()。在这种情况下,所有这些都无关紧要。@Theraot SQL Server做到了,体验也不太理想。只有在Microsoft支持人员指示的情况下,才建议现在使用光纤。光纤需要在应用程序级别进行同步,或非常仔细地编码,以避免阻塞甚至长时间运行CPU绑定的代码