Xml序列化程序(类型)可以随机抛出吗?

本文关键字:随机 程序 序列化 类型 Xml | 更新日期: 2023-09-27 18:34:37

我们有一个令人困惑的情况,正常运行数百次的代码突然停止工作。这是一个通常运行数周的应用程序。

问题是,XmlSerializer(Type)某处是否有一些缓存,可能会损坏?

背景:

在启动时,有一次,我们遇到了很多例外。在检测到问题时重新启动后(几天后(,它再次正常运行。

我们已经将问题追踪到以下代码:

internal static class StateManager
{
    private static XmlSerializer queueSerializer = new XmlSerializer(typeof(List<QueueItem>));
    private static readonly string queuePath = Path.Combine(SubSystem.PersistentDirectory, "Queue.xml");
    internal static void SaveQueue(List<QueueItem> upcomingTasks)
    {
        XmlWriter xmlWriter = XmlWriter.Create(queuePath, xmlSettings);
        queueSerializer.Serialize(xmlWriter, upcomingTasks);
        xmlWriter.Close();
    }
    internal static List<QueueItem> GetQueue()
    {
        var queue = new List<QueueItem>();
        try
        {
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(queuePath);
            using (XmlReader reader = XmlReader.Create(new StringReader(xmlDoc.OuterXml)))
            {
                queue = queueSerializer.Deserialize(reader) as List<QueueItem>;
            }
        }
        catch (Exception e)
        {
            AppTrace.Write(TraceLevel.Error, string.Format("Failed to load State Queue: {0}", e.Message));
        }
        return queue;
    }
}

我们得到的错误是:

Failed to load State Queue: The type initializer for 'StateManager' threw an exception.

据我们了解,这为罪魁祸首留下了两种可能性:

private static XmlSerializer queueSerializer = new XmlSerializer(typeof(List<QueueItem>));

    private static readonly string queuePath = Path.Combine(SubSystem.PersistentDirectory, "Queue.xml");

我们仔细检查了SubSystem.PersistentDirectory,并相信它是无辜的。

由于这发生在客户端机器的现场,我们无法重现它,因此无法检查内部异常。

Xml序列化程序(类型)可以随机抛出吗?

你应该抓住它!我看到那里没有静态 ctor,您可以尝试这样的事情,延迟初始化以便您能够了解更多信息:

internal static class StateManager
{
    private static XmlSerializer queueSerializer;
    private static readonly string queuePath;
    internal static StateManager(){
        try
        {
            queueSerializer = new XmlSerializer(typeof(List<QueueItem>));
            queuePath = Path.Combine(SubSystem.PersistentDirectory, "Queue.xml");
        }
        catch(Exception ex)
        {
            // Log, log, log!
            throw; // Essential: you MUST rethrow!
        }
    }
}

至于实际的违规行,没有办法确定没有痕迹:你所知道的是你的类型无法初始化,没有指示为什么。据我所知,最可能的原因是:

  • 您提供给XmlSerializer的数据中存在某些问题(而不是XmlSerializer本身:我非常怀疑来自 System 命名空间的任何内容都容易随机爆炸(
  • 您的SubSystem.PersistentDirectory包含损坏的数据
  • (不太可能,但你永远不知道...其他内容被破坏,异常实际上与违规代码无关,这些代码可能驻留在其他地方