Исключение FileNotFoundException при десериализации XML

Недавно мы начали видеть, что FileNotFoundException создается спорадически при десериализации XML. Сообщение состоит в том, что временная сборка, используемая для отображения из XML в код, не может быть найдена. Из этот документ выглядит так, как это может произойти, если этот файл не может быть создан .NET Framework (однако причина, по которой это не происходит даже во внутреннем исключении).

Вот исключение:

Type : System.IO.FileNotFoundException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Could not find file 'C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll'.

Имя файла отличается от каждой ошибки, но ошибка всегда одна и та же, она исходит отсюда (полный столбец внизу):

at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)

Когда CSharpCodeGenerator пытается сгенерировать сборку. Мы используем этот код в производстве в течение многих лет, и он был очень стабильным. Он просто начал провал в последнюю неделю или около того. Мы задавались вопросом, может ли это иметь какое-либо отношение к последнему патчу безопасности Microsoft, поскольку это влияет на версию нашего кода в .NET 2.0 и .NET 4.0 на нескольких операционных системах (XP и Server 2003).

Ошибка является спорадической, и запуск процесса снова обычно приводит к его исчезновению. Это однопоточное приложение командной строки, которое извлекает файлы и вставляет их в базу данных.

Я не смог найти кого-либо еще с той же проблемой, но он не изолирован от одной строки кода, у нас есть несколько мест, которые используют код System.Xml.Serialization, и мы видели это ошибка от каждого. Этот код также не является тем, что мы недавно изменили.

Ближайшим другим сообщением, которое я могу найти, является этот.

В нашей QA VM нет антивируса, поэтому я не думаю, что это проблема с этим. Мы также видели эту проблему как в нашей размещенной среде, так и на отдельном клиентском сайте.

Мы попытались:

  • Очистка этого временного каталога
  • Проверка разрешений в каталоге temp (пользователь - локальный администратор).
  • Генерирование XmlSerializers.dll с помощью sgen.exe и развертывание их в папке приложения (проблема сохраняется, как будто .NET Framework не хочет использовать эти сборки).

Если у кого есть какие-то идеи или предложения, которые были бы полезны.

Полный столбец:

Type : System.IO.FileNotFoundException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Could not find file 'C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll'.
Source : mscorlib
Help link : 
FileName : C:\Documents and Settings\user\Local Settings\Temp\c5_nfoko.dll
FusionLog : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Void WinIOError(Int32, System.String)
Stack Trace :    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames)
at Microsoft.CSharp.CSharpCodeGenerator.FromSourceBatch(CompilerParameters options, String[] sources)
at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources)
at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource(CompilerParameters options, String[] sources)
at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence)
at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies)
at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)

Ответ 1

У меня была почти такая же проблема с ASP.NET. Причина в том, что временные DLL файлы, написанные в этой папке, запоминаются где-то, возможно, в ссылках из другой временной библиотеки DLL.

Решение состоит в том, чтобы удалить все файлы в папке C:\Documents and Settings\user\Local Settings\Temp. Некоторые из них, вероятно, будут заблокированы, и вам нужно удалить файлы за несколько итераций, потому что заблокированные файлы, скорее всего, являются источником проблемы (по моему опыту). Когда папка temp понятна, все работает по-разному (по крайней мере для меня).

Ответ 2

Сериализатор XML XML очень плох сам по себе. Исключением, которое вы получаете, является то, что .NET генерирует сборку "на лету" каждый раз, когда вы создаете новый XML-сериализатор. Чтобы предотвратить это как можно больше, используйте словарь с ключом типа, который вы пытаетесь сериализовать, и XML-сериализатор как значение. Такое кэширование позволит вам встретить это первое случайное исключение только в первый раз, когда вы сериализуете неизвестный тип.

Взгляните на веб-сайт Microsoft MSDN, класс XmlSerializer. Есть параграф, который говорит вам, что я только что сказал.