2011-08-25 28 views
29

我對我們的生產基地看到這還有一個小的測試網站,我設置只是爲了測試這一點...MVC3中的錯誤 - 請求永遠不會超時。工作正常,在同一個項目aspx頁面

基本上,它似乎是由請求從未MVC處理時間到。我已經在web.config中設置了一個executionTimeout並關閉了調試模式。然後,我添加了一個無限循環的thread.sleeps到一個普通的aspx頁面和一個mvc頁面(該循環在mvc頁面的控制器中)。 aspx頁面可靠地超時(HttpException(0x80004005):Request timed out。),但是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> 
+1

這也發生在我身上!我很驚訝我沒有看到有人抱怨這個問題! –

+0

看起來像一個框架錯誤! – dan

+0

這是什麼意思?它真的發生在真實場景中嗎? – mare

回答

9

我找到原因了這一點,記錯:

此方法位於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; 
} 

如何在「開始」是:

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;      
      } 
     } 
    } 
} 
+0

這是迄今爲止唯一適用於我的解決方案。 –

+0

你能解釋一下ControllerTimeout在哪裏,如何和什麼? –

+0

基本上,它強制執行控制器的線程在指定的超時時間後中止;有點像燒你的房子殺蜘蛛。 – JerKimball

2

它應該工作當這些條件都滿足:

1)的域名是不是localhost(測試超時,你應該使用「您計算機的名稱」,而不是「本地主機」)。

2)項目編譯爲發佈模式。

3)編譯調試= 「假」

如果不看看這裏的替代(ScriptTimeOut): ASP.NET MVC and httpRuntime executionTimeout

問候,
爸爸

+1

感謝您的回覆,但似乎沒有解決問題。 我現在使用我的計算機的名稱而不是本地主機,我在Visual Studio中以發佈模式編譯它,並在我的web.config中將debug設置爲false。 我也嘗試在我的mvc頁面上設置scriptTimeout屬性,但這也沒有幫助。我認爲這可能是該框架中的一個錯誤。 – Scott

+0

你在其他SO線程中看到過關於沒有〜在路徑中的註釋?也許這是你的問題。我同意它應該在調試中工作。 – whosrdaddy

+0

我沒有使用位置標記,所以沒有路徑。我只想讓這個超時在全球範圍內爲mvc和aspx頁面工作。使用我目前的設置,它對aspx頁面工作正常,但mvc頁面不會超時。 – Scott

0

在MVC 4仍然發生我,我已經提交了這微軟作爲一個bug:

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

更新:

微軟有以下評論:

執行超時功能,不建議在MVC 應用中使用。您可以改爲將HttpContext.Server.ScriptTimeout設置爲 所需的超時值。儘管名字,這是每個請求 設置,應適用於任何ASP.NET請求(名稱爲「腳本」是 誤導)

相關問題