Asp.net 4.0,首次请求目录下的文件时响应很慢

原文:Asp.net 4.0,首次请求目录下的文件时响应很慢

1. 问题起因
2. 尝试过的处理思路
3. 解决方法

 

1. 问题起因

    一个从VS2003(.Net Framework 1.1)升级到.net framework 4.0的项目,每次编译或者部署到服务器上后,首次请求任何一个目录下的默认页面时,都要耗时3~5秒;而以前使用.net framework 1.1的时候,没有这个问题。

我在页面上开启Trace="true"来跟踪,发现页面的处理时间并不久(IIS重启,首次打开页面时截获的信息):

  但是IIS日志中,显示首次请求页面的耗时接近4.635秒。后续连续刷新页面,处理时间比较正常。。

虽然耗时比较久,但页面能够打开;然后我重启IIS,再次打开站点,用VS附加W3WP.exe来进行调试,再次打开这个页面的时候,发现抛出异常了:发生了 System.ArgumentException, Message=已存在具有相同键的条目。

   1: 发生了 System.ArgumentException
   2:   Message=已存在具有相同键的条目。
   3:   Source=System
   4:   StackTrace:
   5:        在 System.Collections.Specialized.ListDictionary.Add(Object key, Object value)
   6:   InnerException: 
   7:     System.dll!System.Collections.Specialized.ListDictionary.Add(object key, object value) + 0x134 字节    
   8:      System.Web.dll!System.Web.UI.ParsedAttributeCollection.AddFilteredAttribute(string filter, string name, string value) + 0xba 字节    
   9:      System.Web.dll!System.Web.UI.TemplateParser.ProcessAttributes(System.Text.RegularExpressions.Match match, out System.Web.UI.ParsedAttributeCollection attribs = {System.Web.UI.ParsedAttributeCollection}, bool fDirective = false, out string duplicateAttribute = null) + 0x221 字节    
  10:      System.Web.dll!System.Web.UI.TemplateParser.ProcessBeginTag(System.Text.RegularExpressions.Match match = {System.Text.RegularExpressions.Match}, string inputText) + 0x68 字节    
  11:      System.Web.dll!System.Web.UI.TemplateParser.ParseStringInternal(string text, System.Text.Encoding fileEncoding) + 0x3d0 字节    
  12:      System.Web.dll!System.Web.UI.TemplateParser.ParseString(string text, System.Web.VirtualPath virtualPath, System.Text.Encoding fileEncoding) + 0x6f 字节    
  13:      System.Web.dll!System.Web.UI.TemplateParser.ParseFile(string physicalPath, System.Web.VirtualPath virtualPath) + 0x115 字节    
  14:      System.Web.dll!System.Web.UI.TemplateParser.ParseInternal() + 0x57 字节    
  15:      System.Web.dll!System.Web.UI.TemplateParser.Parse() + 0x64 字节    
  16:      System.Web.dll!System.Web.Compilation.BaseTemplateBuildProvider.CodeCompilerType.get() + 0x6f 字节    
  17:      System.Web.dll!System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(System.Web.Compilation.BuildProvider buildProvider) + 0x42 字节    
  18:      System.Web.dll!System.Web.Compilation.WebDirectoryBatchCompiler.CompileNonDependentBuildProviders(System.Collections.ICollection buildProviders) + 0xca 字节    
  19:      System.Web.dll!System.Web.Compilation.WebDirectoryBatchCompiler.Process() + 0x5d 字节    
  20:      System.Web.dll!System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(System.Web.Hosting.VirtualDirectory vdir, bool ignoreErrors) + 0x48 字节    
  21:      System.Web.dll!System.Web.Compilation.BuildManager.BatchCompileWebDirectory(System.Web.Hosting.VirtualDirectory vdir, System.Web.VirtualPath virtualDir, bool ignoreErrors) + 0xbc 字节    
  22:      System.Web.dll!System.Web.Compilation.BuildManager.CompileWebFile(System.Web.VirtualPath virtualPath = {System.Web.VirtualPath}) + 0x5d 字节    
  23:      System.Web.dll!System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(System.Web.VirtualPath virtualPath = {System.Web.VirtualPath}, bool noBuild, bool allowCrossApp, bool allowBuildInPrecompile, bool throwIfNotFound, bool ensureIsUpToDate) + 0x141 字节    
  24:      System.Web.dll!System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(System.Web.HttpContext context, System.Web.VirtualPath virtualPath, bool noBuild, bool allowCrossApp, bool allowBuildInPrecompile, bool throwIfNotFound, bool ensureIsUpToDate) + 0x70 字节    
  25:      System.Web.dll!System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(System.Web.VirtualPath virtualPath, System.Web.HttpContext context, bool allowCrossApp, bool throwIfNotFound) + 0x7e 字节    
  26:      System.Web.dll!System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(System.Web.VirtualPath virtualPath, System.Type requiredBaseType = {Name = "Page" FullName = "System.Web.UI.Page"}, System.Web.HttpContext context = {System.Web.HttpContext}, bool allowCrossApp) + 0x35 字节    
  27:      System.Web.dll!System.Web.UI.PageHandlerFactory.GetHandlerHelper(System.Web.HttpContext context, string requestType, System.Web.VirtualPath virtualPath = {System.Web.VirtualPath}, string physicalPath) + 0x20 字节    
  28:      System.Web.dll!System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(System.Web.HttpContext context, string requestType, System.Web.VirtualPath virtualPath, string physicalPath) + 0x29 字节    
  29:      System.Web.dll!System.Web.HttpApplication.MapHttpHandler(System.Web.HttpContext context, string requestType, System.Web.VirtualPath path, string pathTranslated = "。。。。。。。。。。\\order\\default.aspx", bool useAppConfig) + 0xa8 字节    
  30:      System.Web.dll!System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x81 字节    
  31:      System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.MapHandlerExecutionStep}, ref bool completedSynchronously = true) + 0xb9 字节    
  32:      System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception error) + 0x13e 字节    
  33:      System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0xf8 字节    
  34:      System.Web.dll!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {System.Web.Hosting.ISAPIWorkerRequestInProcForIIS7}) + 0x1a2 字节    
  35:      System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x7d 字节    
  36:      System.Web.dll!System.Web.Hosting.ISAPIRuntime.ProcessRequest(System.IntPtr ecb, int iWRType) + 0xfd 字节    
  37:      [应用程序域转换]    
  38:      [本机到托管的转换]   

 

2.  尝试过的处理思路

    我Attach到w3wp上去后,首次访问目录下的默认页面,catch到ArgumentException异常,然后根据异常信息,追踪到 TemplateParser.ParseFile -> ParseString -> ParseStringInternal -> ProcessBeginTag;然后我就尝试了下列努力:

1. 该目录下默认文件的<%@Page ....%>定义,属性与其他文件并没有任何不同(除了CodeBehind和Inherits的值),我把页面里面的内容一点儿一点儿删掉,最后是剩下空内容(只剩下head、body、form几个元素)、空后台代码,问题还依旧存在。

2. 我在这个目录下面,新建了一个页面(VS2010自动生成的,没有添加任何元素或标签),然后把这个新文件作为该目录默认页,发现问题还是存在。

3. 在第2步的基础上,打开新默认页后,我在URL中直接输入旧的默认页,页面瞬间刷出来了。然后我就纠结了,这延时,与页面内容毛的关系都木有,这异常信息也太坑爹了。

4. 出于尝试一下,我试下该目录下的其他文件,首次访问会不会变慢。于是重启IIS,然后发现首次访问该目录中的第一个文件(不论首次访问的是哪个文件),都会耗时数秒;如果Attach到w3wp,都会Catch到这个异常。

5. 项目是从.net framework 1.1(VS2003)上直接升级过来的,以前03的版本,木有这个问题。然后google“asp.net 4.0 slow”,找到下面这个:

    Slow Performance — ASP .NET ASPNET_WP.EXE and CSC.EXE Running After Clicking Redirect Link

6. The very first time that the page is load, then the asp.net compile a lot of pages, almost every one found on the same dir, including modules, and dlls found on bin.也就是说,在首次请求一个目录下的某个文件时,会把该目录的所有文件都编译一下。这样做的好处是,把一个目录的编译操作都集中在首次访问上,后续请求会比较快;但这样带来的问题是,如果编译时间比较久,那第一个发起请求的人就杯具了。于是在配置文件中,设置batch="false",然后问题消失,首次请求的速度提上来了,attach上去也没有异常了。

   

3.  解决方法

   部署的时候,记得在配置文件中,把debug和batch关闭,把optimizeCompilations打开:

    <compilation targetFramework="4.0" debug="false" batch="false" optimizeCompilations="true">

 

标签: asp.net,Performance,compilation,batch,optimizeCompilations

时间: 2024-08-19 21:17:50

Asp.net 4.0,首次请求目录下的文件时响应很慢的相关文章

asp.net实现访问局域网共享目录下文件的解决方法_实用技巧

本文以实例讲述了asp.net实现访问局域网共享目录下文件的解决方法,完整代码如下所示: using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls;

tomcat 6.0.18 work目录下 未保存jsp对应的servelt java文件

问题描述 tomcat 6.0.18 work目录下 未保存jsp对应的servelt java文件 而只有其class文件这个是什么原因呢或者需要怎样配置呢 谢谢! 问题补充:我是直接在myeclipse里的 servers View 里直接选择该工程部署到tomcat服务器里也就相当于直接放在 其webappps目录下的 解决方案 那这个就有点奇怪了.这样试试:你把项目直接拷贝到tomcat的webappps目录下,然后清除缓存,启动tomcat,看能否正常生成文件,如果还是不行,你再拷贝另

PHP统计目录下的文件总数及代码行数(去除注释及空行)

<?php /** * @author xiaoxiao <x_824@sina.com> 2011-1-12 * @link http://xiaoyaoxia.cnblogs.com/ * @license * 统计目录下的文件行数及总文件数··去除注释 */ $obj = new CaculateFiles(); //如果设置为false,这不会显示每个文件的信息,否则显示 $obj->setShowFlag(false); //会跳过所有All开头的文件 $obj->

前两天有人问怎么取得一个目录下的文件,下面就是例子

<%@ Language=VBScript %><%'================================================================'函数名称:FileList'函数功能:列出目录下所有文件'主要参数说明:'1--FolderUrl     虚拟路径  不可为空'2----FileExName    文件扩展名'函数返回值:收文记录'=====================================================

使用python实现正则匹配检索远端FTP目录下的文件

 这篇文章主要介绍了使用python实现正则匹配检索远端FTP目录下的文件的方法,非常的简单实用,需要的小伙伴参考下     遇到一个问题,需要正则匹配远端FTP目录下的文件,如果使用ftp客户端可以通过命令行很容易的做到这一点,但是暂时没有一个工具支持这样的需求,于是通过python对FTP的支持和对正则表达式的支持,写了这么一个简单的工具,用于使用正则表达式来匹配远端目录的文件. 代码如下 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2

PHP遍历并打印指定目录下所有文件实例

 这篇文章主要介绍了PHP遍历并打印指定目录下所有文件实例,需要的朋友可以参考下  代码如下: <?php //功能:遍历并打印指定目录下所有文件   function scan_dir($dir_name,$dir_flag=1) {  static $FILE_COUNT=1;                //记录文件数目 初值为1 目录名称不记  $FILE_COUNT--;                       //每调用一次scan_dir()函数自减1  @$dir_hand

filepath-Pathon 删除指定目录下的文件, 我是coding online,无法调试,代码报错,具体如下:

问题描述 Pathon 删除指定目录下的文件, 我是coding online,无法调试,代码报错,具体如下: #Delete all files under the pointed path import os filePath = raw_input("Input path where you want delete:n") #If file path is null, we should initial the variable "/home" if file

apache 不能访问 cgi-bin目录下的文件

apache 不能访问 cgi-bin目录下的文件 转自:http://www.cnblogs.com/shuang/archive/2008/12/08/1350718.htm 我在本机上配置perl的运行环境老是不成功的原因在于没有去掉httpd.conf中的 ScriptAlias /cgi-bin/ "F:/project/perl/cgi-bin/"前面的"#"(去掉#后还要重起apache,从任务栏的Monitor Apache Servers,否则不起

PHP不用递归遍历目录下所有文件的代码_php实例

实现代码: /** * PHP 非递归实现查询该目录下所有文件 * @param unknown $dir * @return multitype:|multitype:string */ function scanfiles($dir) { if (! is_dir ( $dir )) return array (); // 兼容各操作系统 $dir = rtrim ( str_replace ( '\\', '/', $dir ), '/' ) . '/'; // 栈,默认值为传入的目录 $