Ошибка в MVC3 - запросы никогда не заканчиваются.Работает нормально для ASPX-страниц в том же проекте - PullRequest
30 голосов
/ 26 августа 2011

Я вижу это на нашем производственном сайте, а также на небольшом тестовом сайте, который я настроил только для того, чтобы проверить это ...

По сути, кажется, что запросы, обрабатываемые mvc, никогда не истекают.Я установил executeTimeout в своем web.config и отключил режим отладки.Затем я добавил бесконечный цикл thread.sleeps как к обычной странице aspx, так и к странице mvc (цикл находится в контроллере страницы mvc).Страница aspx надежно истекает (HttpException (0x80004005): истекло время ожидания запроса.), Но страница mvc просто вращается вечно без тайм-аута.

Есть ли отдельные настройки для mvc (я смотрел, но не сделалнашел их)?У mvc запросов нет тайм-аута по умолчанию?

Любая помощь по этому вопросу будет принята.Я с удовольствием вышлю по электронной почте мой небольшой тестовый сайт, если он кому-нибудь поможет.

Редактировать: я использую MVC3.

Содержимое моего web.config:

<?xml version="1.0"?>

<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
  <connectionStrings>
    <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="webpages:Enabled" value="true" />
  </appSettings>

  <system.web>
      <httpRuntime maxRequestLength="16384" executionTimeout="30" />
      <compilation debug="false" targetFramework="4.0">
          <assemblies>
          <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
          </assemblies>
      </compilation>

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>

    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
      </providers>
    </membership>

    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
      </providers>
    </profile>

    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>

  </system.web>

  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Ответы [ 3 ]

9 голосов
/ 30 августа 2011

Я нашел причину для этого, methinks:

Этот метод находится в классе WrappedAsyncResult, который класс MvcHandler использует через 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;
}

, где "Begin" - это:

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);
    }
}

РЕДАКТИРОВАТЬ: придумали неуклюжий способ заставить действия контроллера MVC «тайм-аут», хотя механизм немного грубоват:

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;                    
            }
        }
    }
}
2 голосов
/ 29 августа 2011

Должно работать при соблюдении следующих условий:

1) Доменное имя не является localhost (для проверки тайм-аута следует использовать «YourComputerName» вместо «localhost»).

2)Проект компилируется в режиме Release.

3) debug = "false"

компиляции, если нет, ищите альтернативу (ScriptTimeOut): ASP.NET MVC и httpRuntime executeTimeout

Привет,
Папа

0 голосов
/ 12 марта 2013

Все еще происходит для меня в MVC 4. Я отправил это в Microsoft как ошибку:

https://connect.microsoft.com/VisualStudio/feedback/details/781171/asp-net-mvc-executiontimeout-does-not-work

Обновление:

Microsoft прокомментировала следующее:

Функция тайм-аута выполнения не рекомендуется использовать в приложениях MVC.Вместо этого вы можете установить для HttpContext.Server.ScriptTimeout желаемое значение времени ожидания.Несмотря на название, это параметр для каждого запроса, который должен применяться к любому запросу ASP.NET (имя «script» вводит в заблуждение)

.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...