让我说我的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 有时"神奇地"设置和返回之间的变化,即使没有太多的服务器负载。但是,它始终会更改为在该时间内发送到服务器的值,而不是始终在此请求中发送的值。
所以,我的问题是:
答案 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"];
}