c# - 相同类型对象的 InvalidCastException - 自定义控件加载

标签 c# asp.net compiler-construction user-controls dynamic-compilation

我有一个非常连贯的错误,我的一个自定义控件似乎创建了两个编译文件,当我尝试使用 LoadControl() 动态加载它时只是失败,因为不能将一个转换为另一个 - 即使它们完全相同。我写的帖子看,都是一样的,只是修改了编译的dll。

System.Web.HttpUnhandledException (0x80004005):     
 Exception of type 'System.Web.HttpUnhandledException' was thrown. --->             
    System.InvalidCastException:
[A]ASP.Modules_OneProduct_MedioumImage cannot be cast to
[B]ASP.Modules_OneProduct_MedioumImage.         

   Type A originates from 'App_Web_kg4bazz1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
in the context 'Default'
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_kg4bazz1.dll'.          

   Type B originates from 'App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 
in the context 'Default'    
    at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\80ed7513\10eb08d9\App_Web_oneproduct_mediumimage.ascx.d1003923.4xoxco7b.dll'.

编码

这是我关注后的代码 exactly what is written on MSDN :
foreach (int OneProductID in TheProductIdArrays)
{
    // here is the throw.
    ASP.Modules_OneProduct_MedioumImage OneProduct = 
        (ASP.Modules_OneProduct_MedioumImage)LoadControl(@"~/mod/OneProduct_MediumImage.ascx");

    // do some work with 
    //OneProduct
}

以前我在没有 ASP. 的情况下加载控件但是在出现此错误并寻找解决方案后,我严格遵循 MSDN 上的内容。无论我做什么,错误仍然存​​在。

我也尝试过这两种方法,一种是单独的,一种是一起尝试的(再次失败)
<%@ Register src="~/mod/OneProduct_MediumImage.ascx" tagname="OneProduct_MediumImage" tagprefix="uc1" %>
<%@ Reference Control="~/mod/OneProduct_MediumImage.ascx" %>

配置

我的 web.config,我已经尝试使用 maxBatchSize 20、100、1000,还有 optimizeCompilations true 或 false,但错误再次出现。
<compilation debug="false" defaultLanguage="C#" batch="true"
maxBatchSize="800" batchTimeout="10800" optimizeCompilations="false"
targetFramework="4.0">

现在有关的一些细节
  • 错误是随机的,在某些编译中出现,在其他一些则没有。
  • 这个项目很大,页面上每分钟都有很多人要求看东西,但在没有人的时候也会出现。
  • 在 64 位 dot.net 4 上运行,集成
  • 作为网络花园运行,但也经过测试和一个池(并得到相同的问题)
  • 整个项目的 session 已关闭。
  • 这些页面是从 2007 年开始运行的,但这个问题是上个月出现的,不幸的是我找不到从哪里开始以及如何开始,或者是什么触发了它,因为我迟到了几天才能看到它。
  • 只出现一个自定义控件加载,一个有大量调用的。
  • 我已经更改了 4 次代码进行了小改动,或者大改动,但仍然存在。
  • 我试过 optimizeCompilations真假,同样的问题。
  • 我也尝试过停止网络,删除所有临时文件,重新打开,然后又出现了。
  • 当应用程序当时开始只锁定一个编译时,我尝试在 global.asax 上放置一个互斥锁,但这也失败了。
  • 从有效的那一刻起,一切都很好,但如果无效,则不会自动更正。
  • 我加载此自定义控件的代码存在并在代码上的多个位置、不同页面上调用。
  • 其他具有类似负载的自定义控件没有任何问题。
  • 此自定义控件的 ViewState 已禁用。
  • 我也尝试重新定位一些代码,使用微优化更改完整的函数调用,没有再次失败。
  • 在开发计算机上工作正常。我地batch="true"在 web.config 上,错误立即出现。
  • 没有其他类似的问题,例如我们无论如何都无法修复的错误。系统运行了好几天,池根本不回收,内存稳定,有更多的空闲使用。该程序已运行多年,但我们几乎每天都在更新。
  • 在相同的核心代码下运行多个站点(类似于 stackexchange)并且都具有相同的随机问题。
  • AutoEventWireup 为假
  • 它出现在我以相同方式加载的其他自定义控件上。

  • 当这个错误出现时,我现在做的解决方法是:我只是强制项目以小的更改重新编译,错误消失,直到下一次更新。

    我有一个错误,试图在没有找到原因的情况下解决最后一个树周。我已经尝试了几乎所有我能做的事情,但都失败了,并且错误再次出现。所以我在这里发布也许有些人可以帮助我并找到解决方法。

    最后一句话:这个错误很疯狂,自定义控件是一样的,我对它做任何事情我只动态加载它并且繁荣,编译器由于某种只有他知道的原因有两次不同的时间 - 随机。

    更新 1

    我能够在开发人员机器上重现该错误。在那里我发现包含这个自定义控件的两个 dll 模块有一个不同的。

    一个是捆绑在一起的 4 个自定义控件。另一个模块是单独的自定义控件。

    解决方法

    经过数周尝试修复此错误后,我最终发现当编译器对目录进行批处理编译并在同一个 dll 中捆绑许多不同的自定义控件时,会出现此错误。所以当我尝试单独加载它时会抛出这个异常。

    因此,我将有问题的自定义控件单独移到了不同​​的目录中,并且似乎暂时避免使用它。

    更新 2

    再次出现,即使在我将一些文件移动到不同的目录之后。是随机的,无法找到与触发其的明确联系。

    更新 3

    因为我们发现这里的主要问题是批量编译( batch="true" )在同一个 dll 上编译许多自定义控件,告诉编译器不要这样做的一种方法是 maxBatchGeneratedFileSize 范围。我使用它的值为 100,问题再次出现,现在我将其降低到 40 并进行测试。
    maxBatchGeneratedFileSize="40"
    

    最佳答案

    当您打开批处理并在目录级别具有某种形式的循环引用时,就会发生这种情况。

    请看这个answer确切地了解我在这种情况下所说的“循环引用”是什么意思,因为其含义非常微妙。

    如果您设法打破循环(例如通过将用户控件移到别处),您将不会遇到此问题。

    更新 1

    我认为理论上,这只能由一个循环引起,但有时它们很难检测到。

    我会给你一个我认为可行并且很容易尝试的替代解决方案(即使它有点黑客)。在给您带来问题的用户控件中,在指令中添加以下属性:

    <%@ Control Language="C#" [...] CompilerOptions="/define:dummy1" %>
    

    如果您在其他一些控件中看到这一点,您可以添加相同的内容,但使用 dummy2、dummy3 等...

    这将不会对这个用户控件进行批处理,因为它与其他用户控件有不同的编译需求。从技术上讲,您可以添加任何 C# 命令行作为 CompilerOptions ,但是一个假人 /define是最简单也是最无害的。

    但与全局关闭批处理不同,性能影响将是最小的,因为只有非常小的页面子集不会被批处理。

    顺便说一句,不用说,您所看到的是 ASP.NET 中的一个错误,并且该错误可能已经存在 10 多年了!也许在某个时候它应该得到解决:)

    关于c# - 相同类型对象的 InvalidCastException - 自定义控件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14796546/

    相关文章:

    jquery - jqGrid:使用beforeProcessing填充filterToolbar选择框

    compiler-construction - 如何找到递归语法的FIRST和FOLLOW集?

    c# - 如何在 ColdFusion 中运行 .net 函数

    c# - 从 C# 运行 64 位编译的 MATLAB 函数

    c# - Windows 窗体中的 RSS

    c# - 在 asp.net 中创建 Bot fighter

    c# - 如何排序和排名并选择唯一值?

    asp.net - 单击按钮时如何启动另一个aspx网页?

    java - 如何检查我使用的是哪个版本的 Eclipse 编译器?

    haskell - 如何在编译器中实现源映射?