ASP.NET MVC自定义任务使用什么线程池?

ASP.NET MVC自定义任务使用什么线程池?,asp.net,asp.net-mvc,multithreading,asynchronous,task-parallel-library,Asp.net,Asp.net Mvc,Multithreading,Asynchronous,Task Parallel Library,在Pro ASP.NET MVC 4一书中,有一个异步操作的示例: public class RemoteDataController : AsyncController { public async Task<ActionResult> ConsumeAsyncMethod() { string data = await new RemoteService().GetRemoteDataAsync(); return View("Data", (object)da

在Pro ASP.NET MVC 4一书中,有一个异步操作的示例:

public class RemoteDataController : AsyncController
{
 public async Task<ActionResult> ConsumeAsyncMethod() {
    string data = await new RemoteService().GetRemoteDataAsync();
    return View("Data", (object)data);
 }
}


public class RemoteService 
{
  public async Task<string> GetRemoteDataAsync() {
    return await Task<string>.Factory.StartNew(() => {
            Thread.Sleep(2000);
            return "Hello from the other side of the world";
        });
    }
}
公共类RemoteDataController:AsyncController
{
公共异步任务,其答案或多或少是只应使用库中的异步方法,这些库使用它们自己的线程池

是否可以配置该行为?是否与ASP.NET WebForms的工作方式相同

范例

这是一个非常糟糕的例子。我认为它有三个方面是错误的,但最主要的是正如你所指出的:

任务是否不仅使用线程池中的线程,还用于服务请求

是的,这个例子会

请考虑这个例子来代替:

public class RemoteDataController : Controller
{
  public async Task<ActionResult> ConsumeAsyncMethod() {
    string data = await new RemoteService().GetRemoteDataAsync();
    return View("Data", data);
  }
}

public class RemoteService 
{
  public async Task<string> GetRemoteDataAsync() {
    await Task.Delay(2000);
    return "Hello from the other side of the world";
  }
}
公共类RemoteDataController:控制器
{
公共异步任务ConsumerAsyncMethod(){
字符串数据=等待新的RemoteService().GetRemoteDataAsync();
返回视图(“数据”,数据);
}
}
公共类远程服务
{
公共异步任务GetRemoteDataAsync(){
等待任务。延迟(2000);
返回“来自世界另一边的你好”;
}
}
原始示例使用
thread.Sleep
阻止线程池线程。这在ASP.NET上完全起反作用。一般来说,不要在ASP.NET上使用
Task.Factory.StartNew
Task.Run

相比之下,
Task.Delay
是一种自然异步操作。所谓“自然异步”,我指的是异步操作,就像I/O操作是异步的一样(例如,
HttpClient
用于web调用)。自然异步操作不使用线程,因此它们对ASP.NET服务器有吸引力(减少线程池上的压力,使您可以扩展更多)

想一想这是如何工作的很有趣:当您使用我的示例中的自然异步方法时,一个线程会启动请求,直到它到达
wait
;此时请求线程会返回到线程池(!),在接下来的两秒钟内没有线程处理该请求(但请求尚未完成)。我喜欢将这种现象称为“零线程并发”。当
延迟完成时,一个线程继续处理请求并完成它


另一方面,
AsyncController
是MVC3的一个遗留版本。在
async
/
wait

中不需要它,我确信您在这里故意简化了,但我认为暗示没有使用线程有点危险。没有使用线程池线程,但取决于所做的工作,在这里系统上可能正在使用其他线程。
任务。具体来说,延迟不需要线程,但可能需要其他线程。但是,从web应用程序的角度来看,是的,它将是“无线程的”工作,所以没有错,只是也不完全准确。@ChrisPratt:我的意思是没有线程用于该请求。系统(和应用程序)中的其他地方有各种线程如果您阻止了请求线程,那么这些线程仍然会在那里做同样的事情。即使是
Task.Delay
:BCL实际上有一个“计时器线程”这负责所有托管计时器,因此有一个BCL线程用于计时器。但它是整个AppDomain中的一个线程,而不是每个计时器。同样的原则也适用于此:我们避免了每个请求都需要额外线程的情况。