【问题标题】:Thread handling in ASP.NET Async Await operationsASP.NET Async Await 操作中的线程处理
【发布时间】:2016-06-22 12:41:43
【问题描述】:

对于长时间运行的操作,如果 asp.net 线程被释放到服务器其他请求。长时间运行的操作将在哪个线程上执行,完成后如何获取 asp.net 线程。

【问题讨论】:

    标签: c# asp.net multithreading


    【解决方案1】:

    正如我在博客中所描述的,long-running I/O operations do not require a thread at all。相反,它们使用不需要线程的自然异步 I/O。

    设备驱动程序通常使用 DMA,这允许设备直接读取/写入主系统 RAM。 .NET 通过作为线程池一部分的 IOCP(I/O 完成端口)补充了这种方法,允许每个应用程序域的单个线程(或很少的线程)等待大量 I/O 操作。

    要回答您问题的后半部分,异步方法恢复请求上下文,但它可能会或可能不会在它所在的同一线程上在await 之前。更常见的情况是,当 I/O 操作完成时,它会向 IOCP 发出信号,IOCP 需要一个线程池线程来做一些内务处理(将任务标记为完成等),然后同一个线程进入 ASP.NET请求上下文并继续执行处理程序。这并不总是发生 - 有时线程切换是必要的 - 但这是最​​常见的情况。

    【讨论】:

    • 如果不是 I/O 操作怎么办。如果它是在函数内执行并消耗大量时间的业务逻辑。它不会创建一个新线程。
    • @Sunny:不。如果你使用async而不使用await,那么代码只是直接在调用线程上运行。如果你使用await Task.Run,那么Task.Runnotasync/await)使用单独的线程池线程(注意:在 ASP.NET 上不建议这样做)。
    【解决方案2】:

    回答你的问题,所有线程都是从线程池中抽取的。

    可以这样给出一个示例场景,当服务器接收到请求时,会从池中抽取一个可用线程来为请求提供服务。

    然后你生成一个新线程(通过Async 或其他方式)。现在从池中抽取一个新线程来运行Async 主体的请求。

    同时原始线程被释放到池中并返回处理另一个请求。

    当您的线程完成后,它会从池中取回另一个线程(可能与原始线程不同)并完成您的请求。

    如果此进程受 CPU 限制,那完全是浪费时间,因为您阻塞了一个线程(来自同一个池)。但是 IO 绑定操作可以像这样处理,因为它们不使用线程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      相关资源
      最近更新 更多