【问题标题】:Help on TypeLoadException关于 TypeLoadException 的帮助
【发布时间】:2011-05-31 04:41:13
【问题描述】:

我正在编写一个 .NET 3.5 应用程序 (WinForms),它使用来自外部 DLL 的类,并且每次尝试启动应用程序时,我都会不断收到 System.TypeLoadException。
这是 VS 显示的异常:

System.TypeLoadException 未处理 消息=无法从程序集“PolyMorph,版本=1.0.0.0,文化=中性,PublicKeyToken=null”加载类型“PolyMorph.Common.Settings”。 源=多边形变形 TypeName=PolyMorph.Common.Settings 堆栈跟踪: 在 PolyMorphApp.App.Initialize() 在 PolyMorphApp.App.Main() 在 System.AppDomain._nExecuteAssembly(程序集程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 内部异常:

这是我正在运行的代码:

Friend NotInheritable Class App

    <STAThread()> Shared Sub Main()
        'set the exception handlers'
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
        AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler
        AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler
        'initialize the application'
        App.Initialize()

        'and then run the application'
        Dim mainForm As New PolymorphHost
        Application.Run(mainForm)
    End Sub

    Shared Function Initialize() As FunctionResult
        If App.InitializeDataDirectory() = False Then
            Return New FunctionResult(False, "the application's data directory")
        End If


        _settings = New PolyMorph.Common.Settings(AppDataDirectory & "\Settings.dat")
        ......code continues to load settings from the _settings variable
    End Function
End Class



让我吃惊的是,VS2010 Debugger 在App.Initialize() 行停止,甚至没有进入Initialize 函数。

但是,如果我在 Initialize 函数中注释掉对外部 DLL 的所有引用,则应用程序会正确初始化。


阅读后,我意识到许多报告此错误的人在他们的项目中使用不同的构建(例如从 x86 应用程序引用的 x64 DLL)。因此,我更改了构建配置,因此 DLL 和应用程序都是 x86,但我仍然拥有 TypeLoadException。

我有什么遗漏的吗?

【问题讨论】:

  • 当我的应用程序清单中的 dll 名称错误时出现此错误。

标签: .net vb.net exception typeloadexception


【解决方案1】:

最可能的原因是它在尝试加载其中一项设置时引发异常。您可以尝试在Initialize 方法的第一条语句处设置断点。这可能让您有机会单步执行并查看错误在哪里。

或者您可以在加载每个值后使用Debug 语句(请参阅System.Diagnostics)来确定失败的位置。

【讨论】:

  • 就像我在问题中指出的那样,调试器甚至没有进入 Initialize 方法,因此无法查看可能导致错误的原因。程序根本没有机会加载 any 设置。
  • @Alex:你是对的。对不起。 Paul Alexander 为您指明了正确的方向。
【解决方案2】:

您应该查看 InnerException 和 LoadException 属性,以更详细地了解依赖程序集未正确加载的原因。

它抛出异常之前 Initialize 的原因是由于方法是JIT 编译的方式。当一个方法第一次执行时,CLR 将验证并解析该方法中的所有 MSIL 指令,然后再将其编译为它的运行时等效项。由于 Initialize 方法使用 PolyMorph.Common.Settings 类型,因此 CLR 会在编译时尝试解析它。由于加载失败,因此永远不会执行 Initialize。

要在您自己的代码中捕获异常,只需将整个 Initialize 代码移动到另一个方法,然后在 Initialize 的 try...catch 块中调用该方法。

Try
    InitializeInternal()
Catch ex As TypeLoadException
    System.Diagnostics.Debugger.WriteLine(ex.ToString())
End Try

【讨论】:

  • 我尝试了您提供的代码,但仍然出现异常。该异常在其InnerException 中没有任何数据,顺便说一下我觉得很奇怪,所以我无法追踪异常的来源。
  • @Alex:异常可能在 PolyMorph.Common.Settings 类的 Shared 构造函数中,或者在它的 Shared(静态)初始化程序之一中。
  • @Alex:将调用的全部结果发布到 ex.ToString()。这可能有助于我们提供更多见解。
  • 整个异常与上面的原始问题相同。
【解决方案3】:

似乎有一个 Nutzy 也有一个 similar problem,他通过将所有类、表单和控件复制到一个新项目来解决这个问题。我也这样做了,问题就解决了。

感谢 Jim Mischel 和 Paul Alexander 的协助。我投票支持你帮助我解决问题的努力。

【讨论】:

  • 我遇到了类似的问题。在处理它时,我注意到由于某种原因,我收到了类似“无法删除文件“C:\SomeDll\SomeDll.dll”的警告。拒绝访问路径“C:\SomeDll\SomeDll.dll”。所以我关闭了 Visual Studio,删除了引发错误的 .dll 和 .pdb(因为我无法在 VS 打开的情况下删除它们)并重新启动 Visual Studio。之后问题就解决了。
【解决方案4】:

我遇到了同样的问题,我确信这是 VisualStudio 或 JIT 编译器中的错误。我知道这与 DLL 或 x64 vs x86 无关,因为我的测试项目中没有自定义引用。我将违规行追踪到结构的成员变量。那个特定的成员变量没有什么有趣的(它是一个简单的类:)

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct Foo
    {
        int x;
    }

它是如下成员。如果#if 为真,它会起作用。如果我将它更改为#false,它会编译没有错误,但是在运行时,当我访问整个类中的任何内容时,它会给我 TypeLoadException

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct uartparam_t
    { //size 112
        public UInt16 portnum; //0
        public Byte conntype;
        public Byte baud;
        public Byte databits;
        public Byte stopbits;
        public Byte parity;
        public Byte flowctrl;
#if true
        public int remoteip;
#else
        public Foo remoteip; //8 -- for some reason this is making the program crash! ?!?!?
#endif

     ....

属于

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct config {
 ...
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXUARTPORT)]
        public uartparam_t[] uartparam; //(size 1792)
 ...
    }

这没有任何意义。我尝试完全重建应用程序,以及在新解决方案中创建一个新项目,但这些都没有帮助。使其工作的唯一方法是将结构更改为 int,并在结构之外处理从 int 到 Foo 的类型转换。

【讨论】:

    【解决方案5】:

    当我向我们的产品添加代码时,我经常遇到此错误。我们遇到的问题是 GAC 中安装了最新版本的产品,我正在尝试在我的开发人员机器上测试新功能。我运行的应用程序依赖于我在本地构建的新功能,但该应用程序从 GAC 加载程序集,其中不包含新功能。当我卸载产品时,异常消失了。

    【讨论】:

      【解决方案6】:

      我的问题是父程序集和 DLL 具有相同的程序集名称。

      例如Application.exe 和 Application.dll

      我在项目属性中将每个名称更改为单独的名称(例如 Application.exe 和 Library.dll),它解决了问题。我猜他们正在重新命名项目的选定答案(“转移到新解决方案”)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-01
        • 2011-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多