I\'m seeing this on our production site as well as a small test site I setup just to test this out...
Basically, it appears that requests handled by mvc never time out.
I found the cause for this, methinks:
This method is in the WrappedAsyncResult class, which the MvcHandler class uses via BeginProcessRequest:
public static IAsyncResult BeginSynchronous<TResult>(AsyncCallback callback, object state, Func<TResult> func, object tag)
{
BeginInvokeDelegate beginDelegate = delegate (AsyncCallback asyncCallback, object asyncState) {
SimpleAsyncResult result = new SimpleAsyncResult(asyncState);
result.MarkCompleted(true, asyncCallback);
return result;
};
EndInvokeDelegate<TResult> endDelegate = _ => func();
WrappedAsyncResult<TResult> result = new WrappedAsyncResult<TResult>(beginDelegate, endDelegate, tag);
result.Begin(callback, state, -1);
return result;
}
where "Begin" is:
public void Begin(AsyncCallback callback, object state, int timeout)
{
bool completedSynchronously;
this._originalCallback = callback;
lock (this._beginDelegateLockObj)
{
this._innerAsyncResult = this._beginDelegate(new AsyncCallback(this.HandleAsynchronousCompletion), state);
completedSynchronously = this._innerAsyncResult.CompletedSynchronously;
if (!completedSynchronously && (timeout > -1))
{
this.CreateTimer(timeout);
}
}
if (completedSynchronously && (callback != null))
{
callback(this);
}
}
EDIT: have come up with a ham-handed way of forcing MVC controller actions to "time out", although the mechanism is a bit brutish:
public class TimeoutController : Controller
{
private bool _isExecuting = false;
private int _controllerTimeout = 5000;
private Thread _executingThread;
private readonly object _syncRoot = new object();
protected override void ExecuteCore()
{
_executingThread = Thread.CurrentThread;
ThreadPool.QueueUserWorkItem(o =>
{
Thread.Sleep(_controllerTimeout);
if (_isExecuting)
{
_executingThread.Abort();
}
});
base.ExecuteCore();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
_isExecuting = true;
base.OnActionExecuting(filterContext);
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
_isExecuting = false;
base.OnActionExecuted(filterContext);
}
public int ControllerTimeout
{
get
{
int retVal;
lock(_syncRoot)
{
retVal = _controllerTimeout;
}
return retVal;
}
set
{
lock(_syncRoot)
{
_controllerTimeout = value;
}
}
}
}
It should work when these conditions are met:
1) Domain name is not localhost (to test timeout you should use "YourComputerName" instead of "localhost").
2) Project is compiled in Release mode.
3) compilation debug="false"
if not look here for an alternative (ScriptTimeOut): ASP.NET MVC and httpRuntime executionTimeout
Greetings,
Daddy
Still happening for me in MVC 4. I have submitted this to microsoft as a bug:
https://connect.microsoft.com/VisualStudio/feedback/details/781171/asp-net-mvc-executiontimeout-does-not-work
Update:
Microsoft commented with the following:
The execution timeout feature is not advised to be used in MVC applications. You can instead set HttpContext.Server.ScriptTimeout to the desired timeout value. Despite the name, this is a per-request setting and should apply to any ASP.NET request (the name "script" is misleading)
.