Reputation: 20224
Let's say I have the following ApiController in my ASP.NET WebAPI Application:
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;
}
}
(Reality is a bit more complicated, but this should be all that matters)
This is running fine in my environment and certain others, always returning the input value, even under heavy server load.
In two environments, however, str sometimes "magically" changes between set and return, even without too much server load. However, it always changes to values that were sent to the server around that time, just not always the ones sent in this request.
So, my questions are:
Upvotes: 0
Views: 1429
Reputation: 29207
A request should not modify the state of a controller. From the entry method to any other methods called, you can pass parameters as needed, so there's no need to modify the controller object itself according to the request.
If there's some state that you need to maintain throughout the request that you can't pass through parameters to other methods, the best place to do that is on the HttpContext
since that is always specific to the request. (Even then that scenario probably isn't too common.)
Instead of this:
public string SetStr(string str)
{
this.str = str;
MaybeSleep(); // Some executions take longer, some don't.
return this.str;
}
this:
public string SetStr(string str)
{
HttpContext.Items["str"] = str; //I'd declare a constant for "str"
MaybeSleep();
return HttpContext.Items["str"];
}
Upvotes: 1
Reputation: 62260
Is ApiController reuse a behaviour that I just have to expect, or should a new ApiController be created, used and destroyed for every single request the server processes?
When a request is received, a new controller instance is created by ControllerFactory or DependencyResolver.
Basically, main thread creates a controller instance, and then the same instance is shared between multiple threads until the request is completed.
The rest of the question is not relevant anymore since the first assumption is not correct.
Ideally, if you execute long running process, you want to use a scheduler so that it will not freeze the UI.
You can read more at Scott Hanselman's blog - How to run Background Tasks in ASP.NET
Upvotes: 1