Bug in MVC3 - requests never time out. Works fine for aspx pages in same project

前端 未结 3 556
梦如初夏
梦如初夏 2021-01-31 16:33

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.

相关标签:
3条回答
  • 2021-01-31 17:06

    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;                    
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-31 17:06

    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

    0 讨论(0)
  • 2021-01-31 17:18

    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)

    .

    0 讨论(0)
提交回复
热议问题