XmlSerializer - 文件访问异常

时间:2012-12-16 23:22:42

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

我有一个简单的页面,它从文件系统加载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);
        }
    }
}

但问题是,我有时候会这样做(因为我在PageLoad之后单击“保存”按钮时过于明确)IOException:

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

我试图用互斥锁来锁定块,但它仍然无法正常工作。页面形式非常简单,但我正在使用UpdatePanel(这很重要吗?)。

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

2 个答案:

答案 0 :(得分: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));

答案 1 :(得分:0)

我有类似的问题,我希望这对你也有帮助。 问题是垃圾收集器在第二次点击之前没有清理,所以你应该尝试手动调用它。在生活using

之前尝试调用GC
GC.Collect();
GC.WaitForPendingFinalizers();