2011-08-25 11 views
29

sto vedendo questo sul nostro sito di produzione, nonché un piccolo setup sito di prova ho solo per testare il tutto ...Bug in MVC3 - le richieste non scadono mai. Funziona bene per le pagine aspx in uno stesso progetto

In sostanza, sembra che le richieste gestite da MVC mai tempo scaduto. Ho impostato un timeout di esecuzione nel mio web.config e disattivato la modalità di debug. Ho quindi aggiunto un ciclo infinito di thread.sleeps sia a una normale pagina di aspx che a una pagina di mvc (il loop si trova nel controller della pagina mvc). La pagina di aspx è scaduta in modo affidabile (HttpException (0x80004005): richiesta scaduta.), Ma la pagina mvc gira per sempre senza scadere.

Esistono impostazioni separate per mvc (ho cercato ma non le ho trovate)? Le richieste mvc non scadono per impostazione predefinita?

Qualsiasi aiuto su questo sarebbe apprezzato. Spedirò volentieri il mio piccolo sito di test via email, se potesse aiutare qualcuno.

Modifica: sto utilizzando MVC3.

contenuto del mio 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

Questo sta succedendo anche a me !! Sono sorpreso di non aver visto nessun altro lamentarsi di questo problema! –

+0

sembra un bug di framework! – dan

+0

qual è il punto di questo? In realtà accade mai nello scenario reale? – mare

risposta

9

ho trovato la causa di questo, mi pare :

Questo metodo è nella classe WrappedAsyncResult, che la classe MvcHandler utilizza tramite 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; 
} 

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

EDIT: hanno escogitato un modo prosciutto-handed di costringere azioni di controllo MVC per "time out", anche se il meccanismo è un po 'brutale:

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

Questa è l'unica soluzione che ha funzionato per me finora. –

+0

Puoi spiegare dove, come e cosa sta facendo ControllerTimeout? –

+0

Fondamentalmente, obbliga il thread che esegue il controller ad abortire dopo un periodo di timeout specificato; un po 'come bruciare la tua casa per uccidere un ragno. – JerKimball

2

Dovrebbe funzionare quando queste condizioni sono soddisfatte:

1) nome di dominio non è localhost (per timeout test che si dovrebbe usare "YourComputerName" invece di "localhost").

2) Il progetto è compilato in modalità di rilascio.

3) compilation debug = "false"

se non guardare qui per un'alternativa (ScriptTimeOut): ASP.NET MVC and httpRuntime executionTimeout

Saluti,
papà

+1

Grazie per la risposta, ma non sembra che abbia risolto il problema. Ora sto usando il nome del mio computer piuttosto che localhost, l'ho compilato in modalità di rilascio in Visual Studio e ho impostato il debug su false nel mio web.config. Ho anche provato a impostare la proprietà scriptTimeout sulle mie pagine di mvc, ma questo non ha aiutato neanche. Penso che questo potrebbe essere un bug nel framework. – Scott

+0

Hai visto l'osservazione nell'altro thread SO riguardo a non avere un ~ nel percorso? Forse è questo il tuo problema. Sono d'accordo che dovrebbe funzionare nel debug però. – whosrdaddy

+0

Non sto usando il tag di posizione, quindi non c'è alcun percorso. Voglio solo che questo timeout funzioni a livello globale per le pagine mvc e aspx. Con la mia attuale configurazione funziona bene per le pagine aspx, ma le pagine mvc non scadono. – Scott

0

ancora accadendo per me in MVC 4. ho inviato questo elemento a Microsoft come un bug:

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

Aggiornamento:

Microsoft ha commentato con il seguente:

La funzione di timeout di esecuzione non è consigliato per essere utilizzato in MVC applicazioni. È invece possibile impostare HttpContext.Server.ScriptTimeout su il valore di timeout desiderato.Nonostante il nome, si tratta di una un'impostazione per richiesta e dovrebbe applicarsi a qualsiasi richiesta ASP.NET (il nome "script" è fuorviante )

.

Problemi correlati