首页 新闻 会员 周边

asp.net[WebForm]Debug的时候抛出异常“已存在具有相同键的条目”,但页面能打开,耗时比较久

0
悬赏园豆:20 [已解决问题] 解决于 2012-03-15 13:19

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

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

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

发生了 System.ArgumentException
Message=已存在具有相同键的条目。
Source=System
StackTrace:
在 System.Collections.Specialized.ListDictionary.Add(Object key, Object value)
InnerException:

System.dll!System.Collections.Specialized.ListDictionary.Add(object key, object value) + 0x134 字节
System.Web.dll!System.Web.UI.ParsedAttributeCollection.AddFilteredAttribute(string filter, string name, string value) + 0xba 字节
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 字节
System.Web.dll!System.Web.UI.TemplateParser.ProcessBeginTag(System.Text.RegularExpressions.Match match = {System.Text.RegularExpressions.Match}, string inputText) + 0x68 字节
System.Web.dll!System.Web.UI.TemplateParser.ParseStringInternal(string text, System.Text.Encoding fileEncoding) + 0x3d0 字节
System.Web.dll!System.Web.UI.TemplateParser.ParseString(string text, System.Web.VirtualPath virtualPath, System.Text.Encoding fileEncoding) + 0x6f 字节
System.Web.dll!System.Web.UI.TemplateParser.ParseFile(string physicalPath, System.Web.VirtualPath virtualPath) + 0x115 字节
System.Web.dll!System.Web.UI.TemplateParser.ParseInternal() + 0x57 字节
System.Web.dll!System.Web.UI.TemplateParser.Parse() + 0x64 字节
System.Web.dll!System.Web.Compilation.BaseTemplateBuildProvider.CodeCompilerType.get() + 0x6f 字节
System.Web.dll!System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(System.Web.Compilation.BuildProvider buildProvider) + 0x42 字节
System.Web.dll!System.Web.Compilation.WebDirectoryBatchCompiler.CompileNonDependentBuildProviders(System.Collections.ICollection buildProviders) + 0xca 字节
System.Web.dll!System.Web.Compilation.WebDirectoryBatchCompiler.Process() + 0x5d 字节
System.Web.dll!System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(System.Web.Hosting.VirtualDirectory vdir, bool ignoreErrors) + 0x48 字节
System.Web.dll!System.Web.Compilation.BuildManager.BatchCompileWebDirectory(System.Web.Hosting.VirtualDirectory vdir, System.Web.VirtualPath virtualDir, bool ignoreErrors) + 0xbc 字节
System.Web.dll!System.Web.Compilation.BuildManager.CompileWebFile(System.Web.VirtualPath virtualPath = {System.Web.VirtualPath}) + 0x5d 字节
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 字节
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 字节
System.Web.dll!System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(System.Web.VirtualPath virtualPath, System.Web.HttpContext context, bool allowCrossApp, bool throwIfNotFound) + 0x7e 字节
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 字节
System.Web.dll!System.Web.UI.PageHandlerFactory.GetHandlerHelper(System.Web.HttpContext context, string requestType, System.Web.VirtualPath virtualPath = {System.Web.VirtualPath}, string physicalPath) + 0x20 字节
System.Web.dll!System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(System.Web.HttpContext context, string requestType, System.Web.VirtualPath virtualPath, string physicalPath) + 0x29 字节
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 字节
System.Web.dll!System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x81 字节
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step = {System.Web.HttpApplication.MapHandlerExecutionStep}, ref bool completedSynchronously = true) + 0xb9 字节
System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception error) + 0x13e 字节
System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0xf8 字节
System.Web.dll!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {System.Web.Hosting.ISAPIWorkerRequestInProcForIIS7}) + 0x1a2 字节
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x7d 字节
System.Web.dll!System.Web.Hosting.ISAPIRuntime.ProcessRequest(System.IntPtr ecb, int iWRType) + 0xfd 字节
[应用程序域转换]
[本机到托管的转换]

但重复刷新这个页面的时候,不会出现这个异常。请教这个异常可能是什么原因导致的?谢谢。

 

PS:机器是Windows Server2008, IIS7。

问题补充:

另外,我的项目,是从VS2003(.Net Framework 1.1)升级到.net framework 4.0的。

Silent Void的主页 Silent Void | 初学一级 | 园豆:107
提问于:2012-03-11 11:14
< >
分享
最佳答案
0

代码中有没有ClientScriptManager.RegisterScriptBlock部分

参考内容:An entry with the same key already exists

有没有在控件中设置 EnableViewState=false

参考内容:An error "An entry with the same key already exists" when assigning ImageButton.ImageUrl

收获园豆:15
dudu | 高人七级 |园豆:31007 | 2012-03-13 16:05

谢谢@小小刀@dudu

我的页面也是空页面,IIS Log中记录的信息,后续几次访问,只占用数毫秒的时间。

可能我们被弹出的那个提示误导。

 

很奇怪,我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上去也没有异常了。

 

然后我就奇怪了,我一个目录下,也就不足20个页面,咋就编译这么慢呢。

Silent Void | 园豆:107 (初学一级) | 2012-03-15 13:00

@Silent Void: 

batch="true",会触发预编译。

参见MSDN:“当此特性设置为 True 时, ASP.NET 将以批处理模式预编译所有未编译的文件,第一次编译文件时,这将导致更长时间的延迟。 但在这一初始延迟之后,对文件进行后续访问时,将消除编译延迟。

我写过一篇关于预编译的博文:关于ASP.NET预编译

使用预编译,可以先通过aspnet_compiler命令编译好再发布,这样对网站的影响最小。

dudu | 园豆:31007 (高人七级) | 2012-03-15 13:35
其他回答(1)
0

有源码吗?

看错误信息应该是使用这个字典类型的时候,key值相同导致的。有源码的话,可以看看

System.Collections.Specialized.ListDictionary

收获园豆:5
小小刀 | 园豆:1991 (小虾三级) | 2012-03-11 21:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册