WebAPI控制器重用

时间:2016-07-26 18:53:54

标签: c# asp.net asp.net-web-api

让我说我的ASP.NET WebAPI应用程序中有以下ApiController:

class MyApiController : ApiController
{
    private string str;

     [HttpGet]
    public string SetStr(string str)
    {
        this.str = str;
        MaybeSleep(); // Some executions take longer, some don't.
        return this.str;
    }
}

(现实有点复杂,但这应该是最重要的)

这在我的环境和某些其他环境中正常运行,即使在服务器负载很重的情况下也总是返回输入值。

然而,在两种环境中,str 有时"神奇地"设置和返回之间的变化,即使没有太多的服务器负载。但是,它始终会更改为在该时间内发送到服务器的值,而不是始终在此请求中发送的值。

所以,我的问题是:

  • ApiController是否重用了我所期望的行为,或者是否应该为服务器处理的每个请求创建,使用和销毁新的ApiController?
  • 此行为是否取决于ASP.NET版本,IIS版本和/或Web.config设置?
  • 是否有关于Microsoft提供的私有ApiController变量行为的文档?
  • 或者这可能是某个.NET或ASP.NET版本中的已知错误?

2 个答案:

答案 0 :(得分:1)

  

ApiController是否重用了我不得不期待的行为,或者   应该为每个人创建,使用和销毁新的ApiController   单请求服务器进程?

收到请求后,ControllerFactory或DependencyResolver会创建一个新的控制器实例。

基本上,主线程创建一个控制器实例,然后在多个线程之间共享同一个实例,直到请求完成。

由于第一个假设不正确,问题的其余部分不再相关。

理想情况下,如果执行长时间运行的进程,则需要使用调度程序,以便它不会冻结UI。

您可以在Scott Hanselman的博客上阅读更多内容 - How to run Background Tasks in ASP.NET

答案 1 :(得分:1)

请求不应修改控制器的状态。从entry方法到任何其他调用的方法,您可以根据需要传递参数,因此无需根据请求修改控制器对象本身。

如果在整个请求期间需要维护某些状态,您无法将参数传递给其他方法,那么最好的位置是HttpContext,因为这始终是特定于请求的。 (即便如此,这种情况可能并不常见。)

而不是:

public string SetStr(string str)
{
    this.str = str;
    MaybeSleep(); // Some executions take longer, some don't.
    return this.str;
}

这样:

public string SetStr(string str)
{
    HttpContext.Items["str"] = str; //I'd declare a constant for "str"
    MaybeSleep(); 
    return HttpContext.Items["str"];
}