2

我有一个简单的页面,它从文件系统加载 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(重要吗?)。

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

4

2 回答 2

2

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));
于 2012-12-17T00:04:09.573 回答
0

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

GC.Collect();
GC.WaitForPendingFinalizers();
于 2012-12-16T23:47:41.130 回答