none
大牛,请问怎么知道System.Threading.ThreadAbortException是因为http请求超时导致 RRS feed

  • 问题

  • 在页面Page1.aspx中有如下代码:

    try
                {
    }
     catch (System.Threading.ThreadAbortException ex)
                {
    // 这里获取ex信息
    }
    Global.asax文件:
    protected void Application_Error(Object sender, EventArgs e)
    
    // 写错误信息		{
    }
    我碰到的问题是:当Page1.aspx中给出的代码部分执行时间过长时会因http请求超时而抛出异常System.Threading.ThreadAbortException ,我在"// 这里获取ex信息"这个位置如何知道是因为以上原因导致.
    备注:
    1、当因http请求超时而抛出异常System.Threading.ThreadAbortException 后Global.asax文件能捕获到异常,但那是在Page1.aspx之后捕获的.
    异常信息:
    "错误类型:HttpException
    错误信息:请求已超时。
    错误堆栈:
    "
    2、在.net Framework原代码中有如下代码
    v2.0.50727\dd\ndp\fx\src\xsp\System\Web\HttpApplication.cs:
    internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously) {
                Exception error = null;
     
                try {
                    try { 
                        if (step.IsCancellable) { 
                            _context.BeginCancellablePeriod();  // request can be cancelled from this point
     
                            try {
                                step.Execute();
                            }
                            finally { 
                                _context.EndCancellablePeriod();  // request can be cancelled until this point
                            } 
     
                            _context.WaitForExceptionIfCancelled();  // wait outside of finally
                        } 
                        else {
                            step.Execute();
                        }
     
                        if (!step.CompletedSynchronously) {
                            completedSynchronously = false; 
                            return null; 
                        }
                    } 
                    catch (Exception e) {
                        error = e;
    
                        // Since we will leave the context later, we need to remember if we are impersonating 
                        // before we lose that info -
                        if (ImpersonationContext.CurrentThreadTokenExists) { 
                            e.Data[System.Web.Management.WebThreadInformation.IsImpersonatingKey] = String.Empty; 
                        }
                        // This might force ThreadAbortException to be thrown 
                        // automatically, because we consumed an exception that was
                        // hiding ThreadAbortException behind it
    
                        if (e is ThreadAbortException && 
                            ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == 0))  {
                            // Response.End from a COM+ component that re-throws ThreadAbortException 
                            // It is not a real ThreadAbort 
                            //
                            error = null; 
                            _stepManager.CompleteRequest();
                        }
                    }
                    catch { 
                        // ignore non-Exception objects that could be thrown
                    } 
                } 
                catch (ThreadAbortException e) {
                    // ThreadAbortException could be masked as another one 
                    // the try-catch above consumes all exceptions, only
                    // ThreadAbortException can filter up here because it gets
                    // auto rethrown if no other exception is thrown on catch
     
                    if (e.ExceptionState != null && e.ExceptionState is CancelModuleException) {
                        // one of ours (Response.End or timeout) -- cancel abort 
     
                        CancelModuleException cancelException = (CancelModuleException)e.ExceptionState;
     
                        if (cancelException.Timeout) {
                            // Timed out   注意这里的Timeout
                            error = new HttpException(SR.GetString(SR.Request_timed_out),
                                                null, WebEventCodes.RuntimeErrorRequestAbort); 
                            PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);
                        } 
                        else { 
                            // Response.End
                            error = null; 
                            _stepManager.CompleteRequest();
                        }
    
                        Thread.ResetAbort(); 
                    }
                } 
     
                completedSynchronously = true;
                return error; 
            }

    v2.0.50727\dd\ndp\fx\src\xsp\System\Web\HttpContext.cs:
    // call a delegate within cancellable period (possibly throwing timeout exception) 
            internal void InvokeCancellableCallback(WaitCallback callback, Object state) {
                if (IsInCancellablePeriod) {
                    // call directly
                    callback(state); 
                    return;
                } 
     
                try {
                    BeginCancellablePeriod();  // request can be cancelled from this point 
    
                    try {
                        callback(state);
                    } 
                    finally {
                        EndCancellablePeriod();  // request can be cancelled until this point 
                    } 
    
                    WaitForExceptionIfCancelled();  // wait outside of finally 
                }
                catch (ThreadAbortException e) {
                    if (e.ExceptionState != null &&
                        e.ExceptionState is HttpApplication.CancelModuleException && 
                        ((HttpApplication.CancelModuleException)e.ExceptionState).Timeout) {
     // 注意上面的Timeout
                        Thread.ResetAbort(); 
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);
     
                        throw new HttpException(SR.GetString(SR.Request_timed_out),
                                            null, WebEventCodes.RuntimeErrorRequestAbort);
                    }
                } 
            }

    上面的信息可以看出通过在Page1.aspx中的ex.ExceptionState判断是否是HttpApplication.CancelModuleException且其Timeout为true能作为判断条件,但HttpApplication.CancelModuleException是protected,即Page1.aspx无法直接访问。
    等待大牛。。。。。。。。。。。。。。
    2009年7月24日 0:54

答案

  • 常见的超时有几种,上面的是一种。
    另外常见的有 
    SqlConnection 默认超时为 5  秒,可以在连字符串中指定;
    SqlCommand  默认为 30 秒,可以通过SqlCommand.CommandTimeout 指定;

    知识改变命运,奋斗成就人生!
    2009年7月24日 2:31
    版主

全部回复

  • 你好,你仔细看,最后抛出的错误是 HttpException , 你用这个类型就行了
    知识改变命运,奋斗成就人生!
    2009年7月24日 1:44
    版主
  • 不行啊,
    // <strong>注意上面的Timeout
    </strong>                    Thread.ResetAbort();
                        PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT);

                       
    throw new HttpException(SR.GetString(SR.Request_timed_out),
                                           
    null, WebEventCodes.RuntimeErrorRequestAbort);

    ThreadAbortException 比HttpException先触发,即Page1.aspx中的捕获了ThreadAbortException 后Global.asax才捕获到HttpException。而我的问题是在Page1.aspx中捕获ThreadAbortException里的时候想知道抛出次异常的原因,而此时HttpException还没有抛出。

    2009年7月24日 1:55
  • 我想知道的其实是怎么知道当前页面的请求已超时。
    2009年7月24日 2:06
  • <configuration>
      <system.web>
        <httpRuntime executionTimeout="600"/>
      </system.web>
    </configuration>

    默认的超时时间为 110 秒, 你可以在web.config 中添加上面的内容增大这个时间





    知识改变命运,奋斗成就人生!
    2009年7月24日 2:21
    版主
  • 谢谢版主,增大超时时间还是有可能超时,不够彻底,还是有个定时炸弹放着,睡不着
    2009年7月24日 2:25
  • 常见的超时有几种,上面的是一种。
    另外常见的有 
    SqlConnection 默认超时为 5  秒,可以在连字符串中指定;
    SqlCommand  默认为 30 秒,可以通过SqlCommand.CommandTimeout 指定;

    知识改变命运,奋斗成就人生!
    2009年7月24日 2:31
    版主
  • 是的,谢
    2009年7月24日 3:43