【问题标题】:XmlSerializer - File access ExceptionXmlSerializer - 文件访问异常
【发布时间】:2012-12-16 23:22:41
【问题描述】:

我有一个简单的页面,它从文件系统加载 XML,填充文本框,这些可以更新和保存。对于序列化和反序列化,我使用这些方法:

private static readonly object FormDataLock = new object();

public static FormData getFormData(string filename)
{
    FormData fd;
    lock (FormDataLock)
    {
        XmlSerializer x = new XmlSerializer(typeof(FormData));
        using (Stream s = new FileStream(filename, FileMode.Open, FileAccess.Read))
        {
            return (FormData)x.Deserialize(s);
        }
    }
}

public void saveFormData(string filename)
{
    lock (FormDataLock)
    {
        XmlSerializer x = new XmlSerializer(typeof(FormData));
        using (Stream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
        {
            x.Serialize(s, this);
        }
    }
}

但问题是,我有时会遇到 IOException:

IOException: The process cannot access the file ".." because it is being used by another process. 

我试图用互斥锁锁定块,但它仍然不能正常工作。页面表单非常简单,但我在上面使用了 UpdatePanel(重要吗?)。

当页面加载完成并且第一次保存请求完成后,我可以尽可能快地点击按钮,一切正常(没有例外)。

【问题讨论】:

    标签: c# asp.net xml-serialization file-access


    【解决方案1】:

    XmlSerialization 动态创建新的 dll,这些 dll 特定于您尝试在 temp 目录中序列化的类。创建这些是为了提高性能。 见http://msdn.microsoft.com/en-us/library/swxzdhc0.aspx

    不要调用 GC.Collect 等...尝试将序列化程序创建为类上的静态字段。这应该会提高性能并可能会解决您的问题,因为它只会被创建一次。

    此代码将以线程安全的方式创建单个 xmlserializer。不要为此添加 [ThreadStatic] 属性,因为这将确保每个线程执行一次代码并使其再次成为线程不安全!

    private static readonly XmlSerializer xmlSerializer = 
        new XmlSerializer(typeof(FormData));
    

    【讨论】:

    • 正如我在上一篇文章中所写 - 我在这里找到了这个解决方案:theroks.com/…,我也尝试过,但我认为它没有解决问题。
    • 所以我又试了一次(我以前没有使用过 [ThreadStatic]),似乎没问题 - 问题是当我之前尝试它时,我可能把它弄坏了,以至于在新的使用单例编译解决方案的文件仍被先前的测试锁定。
    • 所以不需要 GC.Collect?
    • 我已经尝试了这个解决方案一段时间,问题都没有了,而且它似乎比 GC.Collect 更好,因为它更快。
    【解决方案2】:

    我也遇到过类似的问题,希望对你也有帮助。 问题是垃圾收集器在您第二次单击之前没有清理,因此您应该尝试手动调用它。活着之前尝试调用GCusing

    GC.Collect();
    GC.WaitForPendingFinalizers();
    

    【讨论】:

    • 请不要乱用 GC,除非你完全知道自己在做什么。如果您必须强制 GC,大多数情况下,这表明您的代码存在问题。
    • 又好又快 :) 我可能永远找不到这个解决方案。所以它似乎运作良好。如果问题再次出现,我会向您发送反馈。谢谢。
    • Eugene - 我正在搜索我发布的代码是否存在任何可能的问题,但我没有运气。我发现只有一个线索在这里:theroks.com/…(有一些关于 XMLSerializer 可能泄漏的信息),但是在实现为单例后问题仍然存在。
    • @Eugene 如果您使用using 语句,您正在等待在您离开后立即调用 GC。否则没有使用它的意义。至少告诉我一个不在这样的地方手动调用 GC 的充分理由?
    • 我同意尤金的观点。调用 GC 几乎总是一种代码异味。你不应该这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2012-03-12
    相关资源
    最近更新 更多