C# ApplicationSettingsBase中的FileNotFoundException

C# ApplicationSettingsBase中的FileNotFoundException,c#,application-settings,applicationsettingsbase,C#,Application Settings,Applicationsettingsbase,调试应用程序时,如果在VisualStudio中启用了中断异常,我总是会遇到以下错误。这真的让我烦透了,因为我们是在破例时工作的。有趣的是,当我继续(StringCollection已加载)时,它仍然有效 信息是: 无法加载文件或程序集“System.XmlSerializers,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”或其依赖项之一。系统找不到指定的文件 以下是导致异常的代码(设计器生成) 我试图创建一个显

调试应用程序时,如果在VisualStudio中启用了中断异常,我总是会遇到以下错误。这真的让我烦透了,因为我们是在破例时工作的。有趣的是,当我继续(StringCollection已加载)时,它仍然有效

信息是:

无法加载文件或程序集“System.XmlSerializers,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”或其依赖项之一。系统找不到指定的文件

以下是导致异常的代码(设计器生成)


我试图创建一个显示错误的空测试应用程序,但异常没有发生。我们的项目很大,所以很难找到原因。可能这个站点上的某个人知道如何解决这个问题。

如果捕获的异常太多,System.XmlSerializer将始终抛出此异常作为其正常操作的一部分,它由类本身捕获和处理。更改调试选项,使其仅捕获异常,而不捕获.net farmework类中捕获和处理的异常。

,因为这似乎是正常操作的一部分(另请参见: ),我只能提供两个解决方案:

禁用此特定异常:Goto调试/异常,单击Add,类型:C++异常,名称:EEFLILOODAXEXCEDE(如果这是您所看到的异常),取消检查此异常的抛出复选框。< /P> 将设置类型更改为字符串并访问它,例如:

var mru = Settings.Default.Mru.Split('|');
Settings.Default.Mru = string.Join("|", mru.ToArray());

只是解释为什么会抛出此异常。您可以使用此示例Windows窗体应用程序重新设置异常。首先添加一个名为“setting”的StringCollection类型的设置。单击“值”列中的点并输入两个字符串。使表单类代码如下所示:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    protected override void OnFormClosing(FormClosingEventArgs e) {
        Properties.Settings.Default.Setting[0] = DateTime.Now.ToString();
        Properties.Settings.Default.Save();
        base.OnFormClosing(e);
    }
}
mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes 
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes   
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes   
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes  
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes  
调试+异常,勾选CLR异常的抛出复选框。运行表单并关闭它,当抛出异常时,调试器将停止。调用堆栈的顶部如下所示:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    protected override void OnFormClosing(FormClosingEventArgs e) {
        Properties.Settings.Default.Setting[0] = DateTime.Now.ToString();
        Properties.Settings.Default.Save();
        base.OnFormClosing(e);
    }
}
mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes 
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes   
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes   
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes  
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes  
您可以看到XmlSerializer类正在寻找包含StringCollection类的XML序列化程序集的程序集。移除钻孔钻头后,LoadGeneratedAssembly方法如下所示:

internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract)
{
    ...
    AssemblyName parent = GetName(type.Assembly, true);
    partialName = Compiler.GetTempAssemblyName(parent, defaultNamespace);
    parent.Name = partialName;
    parent.CodeBase = null;
    parent.CultureInfo = CultureInfo.InvariantCulture;
    try
    {
        serializer = Assembly.Load(parent);      // <=== here
    }
    catch (Exception exception)
    {
      ...
    }
  ....
}
这个名字就是这个案子的作恶者。StringCollection类位于System.dll程序集中,该方法生成名称“System.XmlSerializers”。此方法旨在为您自己的类(由Sgen.exe生成的类)查找程序集。类似于示例程序的WindowsApplication1.XmlSerializers.dll。但是StringCollection是.NET Framework中的一个类,它生成的程序集名称无效。框架中实际上没有“System.XmlSerializers.dll”程序集

connect.microsoft.com上有关此行为的反馈报告均已通过“按设计”关闭。事实上,最初的设计师认为防止异常的成本太高,决定只捕获异常。这一切都很好,例外情况确实被抓住了。您刚好看到它,因为您在“调试+异常”对话框中打开了“抛出”复选框


在这里,让Xml序列化代码表现出不同的行为不是一个选项。对他们来说,简单地过滤掉System.dll程序集中的类型是很容易的,但这可能是一场永无止境的战斗,因为框架中还有更多的程序集。解决方法是使用您自己的类来存储设置,而不是使用StringCollection。

+1,是的。我非常讨厌System.Xml,它不是最重要的部分之一。正如我所说,在测试应用程序中,相同的设置属性不会出现异常。所以XmlSerializer不会总是抛出这个异常,也许不是每次,我没有彻底测试过每一种可能的情况。但这不是重点,重点是它是类操作的一个正常部分,如果您根本没有调试,或者如果您没有捕获由代码以外的代码引发的异常,那么您将看不到它。这不是一个简单的错误,这门课是如何工作的。谢谢你的详细解释。我尽量避免在将来使用StringCollection。太糟糕了,这是“按设计”。所以简短的答案是在调试>异常中,从抛出中删除检查?