Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XmlSerializer未使用sgen创建的XmlSerializers.dll_C#_.net_Xml Serialization_Sgen - Fatal编程技术网

C# XmlSerializer未使用sgen创建的XmlSerializers.dll

C# XmlSerializer未使用sgen创建的XmlSerializers.dll,c#,.net,xml-serialization,sgen,C#,.net,Xml Serialization,Sgen,在我的VisualStudio2010项目中,我使用以下生成后事件命令行使用sgen创建XmlSerializers.dll 生成后事件: "$(ProgramFiles)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" /a:"$(TargetPath)" /c:/keyfile:"c:\myproject\mykey.snk" /f 我的项目是强名称的,所以使用相同的键来强名称“XmlSerializers.dll”。V

在我的VisualStudio2010项目中,我使用以下生成后事件命令行使用sgen创建XmlSerializers.dll

生成后事件:

"$(ProgramFiles)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" /a:"$(TargetPath)" /c:/keyfile:"c:\myproject\mykey.snk" /f
我的项目是强名称的,所以使用相同的键来强名称“XmlSerializers.dll”。VS在输出文件夹中创建XmlSerializers.dll

但是,我注意到,使用ProcessMonitor,.NET仍然在运行时调用CSC.exe。我遇到了这个问题,用户遇到了类似的问题,并通过使用XmlSerializer(Type)构造函数解决了这个问题

我在代码中使用了相同的技术,但它仍然调用csc.exe:

var fs = new FileStream(SettingsFilePath, FileMode.Open);
try
{
var serializer = new XmlSerializer(typeof(AppSettings));
settings = (AppSettings)serializer.Deserialize(fs);
}
finally
{
fs.Close();
}
我之所以需要使用预编译XML序列化,是因为性能原因,而且我有时在Windows关机时看到csc.exe出错。我的应用程序在窗体关闭时保存数据,在关闭过程中,由于Windows不允许在关闭顺序期间启动新进程,因此应用程序失败。我看到了一些建议,建议通过预编译XML序列化来解决这个问题

关于XmlSerializer为什么不使用sgen创建的XmlSerializers.dll,有什么建议吗

谢谢。

您尝试过在生成的dll上运行吗

运行

ngen.exe install myproject.XmlSerializers.dll

将在映像缓存中安装dll的本机映像,该映像应在运行时使用,而不是调用JIT编译器。

可能的问题是不同的目标平台:默认情况下,如果包含要反序列化或序列化类型的程序集是为x86 o x64编译的,则sgen使用“任意CPU”(MSIL),它不会加载
.XmlSerializers.dll

更一般地说,我查看了加载序列化程序集的.NET代码-以下是一些与单元测试重现相同行为的代码:

/// <summary>Generates an identifier for the assembly of a specified type</summary>
/// <remarks>Code copied from the .NET serialization classes - to emulate the same bahavior</remarks>
/// <param name="type">The type</param>
/// <returns>String identifying the type's assembly</returns>
static string GenerateAssemblyId(Type type) 
{ 
  Module[] modules = type.Assembly.GetModules();
  ArrayList list = new ArrayList();
  for (int i = 0; i < modules.Length; i++) {
    list.Add(modules[i].ModuleVersionId.ToString()); 
  }
  list.Sort(); 
  StringBuilder sb = new StringBuilder(); 
  for (int i = 0; i < list.Count; i++) {
    sb.Append(list[i].ToString()); 
    sb.Append(",");
  }
  return sb.ToString();
} // GenerateAssemblyId

/// <summary>Verifies that the serialization assembly for the specified type can be loaded</summary>
/// <remarks>Code copied from the .NET serialization classes - to emulate the same behavior and tests</remarks>
/// <param name="type">The type</param>
static void AssertCanLoadXmlSerializers(Type type)
{
  if (type == null)
    throw new ArgumentNullException("type");
  Assembly serializerAssembly = null;
  // Create the name of the XML serilizers assembly from the type's one
  AssemblyName name = type.Assembly.GetName(true); 
  name.Name = name.Name + ".XmlSerializers"; 
  name.CodeBase = null;
  name.CultureInfo = CultureInfo.InvariantCulture;
  try {
    serializerAssembly = Assembly.Load(name);
  } catch (Exception e) {
    Assert.Fail("Unable to load XML serialization assembly for type '{0}': {1}", type.FullName, e.Message);
  }
  object[] attrs = serializerAssembly.GetCustomAttributes(typeof(XmlSerializerVersionAttribute), false);
  if (attrs == null || attrs.Length == 0) {
    Assert.Fail(
      "Unable to use XML serialization assembly '{1}' for type '{0}': it does not contain XmlSerializerVersionAttribute", 
      type.FullName, 
      serializerAssembly.FullName
    );
  }
  if (attrs.Length > 1) {
    Assert.Fail(
      "Unable to use XML serialization assembly '{1}' for type '{0}': it contains multiple XmlSerializerVersionAttribute", 
      type.FullName, 
      serializerAssembly.FullName
    );
  }
  XmlSerializerVersionAttribute assemblyInfo = (XmlSerializerVersionAttribute)attrs[0];
  string assemblyId = GenerateAssemblyId(type);
  if (assemblyInfo.ParentAssemblyId != assemblyId) {
    Assert.Fail(
      "Unable to use XML serialization assembly '{1}' for type '{0}': it does not match assembly id '{2}'", 
      type.FullName, 
      serializerAssembly.FullName,
      assemblyId
    );
  }
} // AssertCanLoadXmlSerializers
///为指定类型的程序集生成标识符
///从.NET序列化类复制的代码-用于模拟相同的bahavior
///类型
///标识类型的程序集的字符串
静态字符串GenerateAssemblyId(类型)
{ 
Module[]modules=type.Assembly.GetModules();
ArrayList=新建ArrayList();
对于(int i=0;i1){
断言失败(
无法将XML序列化程序集“{1}”用于类型“{0}”:它包含多个XmlSerializerVersionAttribute”,
type.FullName,
serializembly.FullName
);
}
XmlSerializerAsionAttribute assemblyInfo=(XmlSerializerAsionAttribute)属性[0];
string assemblyId=GenerateAssemblyId(类型);
if(assemblyInfo.ParentAssemblyId!=assemblyId){
断言失败(
无法对类型“{0}”使用XML序列化程序集“{1}”:它与程序集id“{2}”不匹配,
type.FullName,
serializembly.FullName,
汇编ID
);
}
}//AssertCanLoadXmlSerializers
只需调用
AssertCanLoadXmlSerializers()
传递需要序列化/反序列化的类型。如果未加载序列化程序集,则可以从错误消息中很好地了解原因


我将它添加到我们的单元测试中,以便合理地确定序列化程序集是正常的。

您确定序列化程序集已正确签名吗?通常你需要转义引号。有关更多信息,请参阅

您还可以检查ID是否匹配。如果在生成序列化程序集后修改源程序集,则ID将不再匹配,并且将不会使用序列化程序集。有关更多信息,请参阅


如果所有这些都正确:禁用工具->选项->调试->仅启用我的代码”并启用调试->执行->公共语言运行时异常->抛出。然后调试应用程序,直到序列化完成。将引发第一次异常,说明无法使用序列化程序集的原因。

解决关闭问题的最简单方法是在启动时加载数据。使用fuslogvw.exe检查程序集解析。谢谢,我需要在MainForm关闭时保存数据(序列化为XML)。正常关闭期间由用户进行,无误,数据序列化。但是,如果我的应用程序正在运行且Windows关闭,则我会看到CSC.exe错误。谢谢,我尝试了您关于使用ngen.exe的建议,但仍然在ProcessMonitor中看到cse.exe调用。这是ProcessMonitor的屏幕截图:“DataSerializer.XmlSerializers.dll”是由sgen创建的序列化程序dll。此代码非常有用。非常感谢。我试图理解如果断言在最后一个块上失败(“它与程序集id不匹配”),如何更正该问题。你能支持我吗