2011-08-25 5 views
29

Widzę to na naszej stronie produkcyjnej, a także w małej witrynie testowej, którą skonfigurowałem, aby przetestować to ...Błąd w MVC3 - żądania nigdy nie kończą się. Działa dobrze na stronach aspx w tym samym projekcie

Zasadniczo wygląda na to, że wnioski rozpatrywane przez mvc nigdy koniec czasu. Ustawiłem executionTimeout w moim web.config i wyłączyć tryb debugowania. Dodałem nieskończoną pętlę thread.sleeps do zwykłej strony aspx i strony mvc (pętla znajduje się w kontrolerze strony mvc). Strona aspx niezawodnie przekracza limit czasu (wyjątek HttpException (0x80004005): żądanie przekroczenia limitu czasu.), Ale strona mvc obraca się na zawsze bez limitu czasu.

Czy są dostępne osobne ustawienia dla mvc (sprawdziłem, ale ich nie znalazłem)? Czy żądania mvc nie są domyślnie ustawione na timeout?

Każda pomoc w tym zakresie byłaby doceniana. Chętnie wyślę e-mail z mojej małej witryny testowej, jeśli to pomoże nikomu.

Edytuj: Używam MVC3.

Zawartość mojego 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> 
+1

To też mi się przydarza !! Jestem zaskoczony, że nie widziałem nikogo innego narzekającego na ten problem! –

+0

wygląda jak błąd w ramce! – dan

+0

o co w tym chodzi? Czy rzeczywiście dzieje się to w prawdziwym scenariuszu? – mare

Odpowiedz

9

znalazłem przyczynę tego, methinks :

Ta metoda znajduje się w klasie WrappedAsyncResult, której klasa MvcHandler używa za pomocą 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; 
} 

gdzie „Początek” jest:

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: wymyślić szynka uczynku sposób wymuszenia działania kontrolera MVC do „time out”, choć mechanizm jest nieco brutalny:

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

To jedyne rozwiązanie, które dotychczas działało dla mnie. –

+0

Czy możesz wyjaśnić, gdzie, jak i co robi ControllerTimeout? –

+0

Zasadniczo zmusza on wątek wykonujący kontroler do przerwania po określonym czasie oczekiwania; trochę jak spalenie domu, by zabić pająka. – JerKimball

2

Powinien działać, gdy spełnione są te warunki:

1) nazwa domeny nie jest localhost (do limitu czasu testowego należy użyć „YourComputerName” zamiast "Lokalny Gospodarz").

2) Projekt jest kompilowany w trybie Release.

3) kompilacja debug = "false"

jeśli nie wyglądają tu alternatywy (ScriptTimeOut): ASP.NET MVC and httpRuntime executionTimeout

Pozdrowienia,
Tato

+1

Dziękuję za odpowiedź, ale to nie rozwiązało problemu. Używam teraz nazwy komputera, a nie lokalnego hosta, skompilowałem go w trybie zwolnienia w visual studio i ustawiłem debugowanie na false w moim pliku web.config. Próbowałem też ustawić właściwość scriptTimeout na moich stronach mvc, ale to też nie pomogło. Myślę, że może to być błąd w strukturze. – Scott

+0

Widziałeś uwagę w innym wątku SO o tym, że nie ma ~ na ścieżce? Może to twój problem. Zgadzam się, że powinien działać w debugowaniu. – whosrdaddy

+0

Nie używam tagu lokalizacji, więc nie ma ścieżki. Chcę tylko, aby ten limit czasu działał na poziomie globalnym dla stron mvc i aspx. Z moją obecną konfiguracją działa dobrze dla stron aspx, ale strony mvc nie będą limitowane. – Scott

0

Wciąż dzieje się dla mnie w MVC 4. I przedstawiły to Microsoft jako błąd:

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

Aktualizacja:

Microsoft skomentował z następujących czynności:

Funkcja Timeout wykonanie nie jest zalecane do stosowania w MVC zastosowań. Zamiast tego można ustawić wartość HttpContext.Server.ScriptTimeout na żądaną wartość limitu czasu.Pomimo nazwy, czy jest to ustawienie per-żądanie i powinna mieć zastosowanie do każdego wniosku ASP.NET (nazwa „skrypt” jest mylące)

.

Powiązane problemy