锁定XML文件中的Web应用程序 [英] Locking XML file in Web Application

查看:144
本文介绍了锁定XML文件中的Web应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个网站应用程序,它作为一个表单设计器。

的形式的数据存储在XML文件中。每种形式都有它自己的XML文件。

当我编辑的形式,我基本上重新创建XML文件。

 公共无效保存(GUID form_Id,IEnumerable的< FORMDATA> FORMDATA)
{
    DOC的XDocument =新的XDocument();
    的XElement formsDataElement =新的XElement(FormsData);
    doc.Add(formsDataElement);
    的foreach(在FORMDATA FORMDATA数据)
    {
        formsDataElement.Add(新的XElement(FORMDATA
                                 新XAttribute(ID,data.Id)
                                 新XAttribute(名,data.Name)
                                 //其他属性
                             ));
    }    doc.Save(formXMLFilePath);
}

这工作不错,但我想,以确保两个用户不会在同一时间XML文件进行更新。我想以某种方式将其锁定。

如何单独锁定保存过程的每个文件?

我可以锁定保存功能类似下面,但是这将锁定所有用户,即使它们保存为不同的XML文件。

 私有静态只读对象_lock =新的对象();
公共无效保存(GUID form_Id,IEnumerable的< FORMDATA> FORMDATA)
{
    锁(_lock)
    {
        DOC的XDocument =新的XDocument();
        的foreach(在FORMDATA FORMDATA数据)
        {
            // code
        }        doc.Save(formXMLFilePath);
    }
}


解决方案

尝试是这样的:

 的FileStream文件=新的FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);尝试{
    doc.Save(文件);
} {最后
    file.Close();
}

这使用了的FileStream 和我们提供了文件共享模式。在我们的例子中,我们的完全的锁定文件,以便只有我们可以写它。

然而,这仅仅意味着是有锁后续写入将失败。

要解决这个问题,我倾向于有一个队列和一个单独的线程谁的唯一工作就是处理队列和写入文件系统。

但另一种解决方案是简单地尝试访问该文件,如果失败等待一点点,然后再试一次。这将让你做一些类似于锁定在那里等待,直到它可以访问,然后继续:

 私有静态布尔IsLocked(字符串文件名)
{
    如果(!File.Exists(文件名))返回false;    尝试{
        的FileStream文件=新的FileStream(文件名,FileMode.Open,FileAccess.Write,FileShare.None);        尝试{
            返回false;
        } {最后
            file.Close();
        }
    }赶上(IOException异常){
        返回true;
    }
}公共无效保存(GUID form_Id,IEnumerable的< FORMDATA> FORMDATA)
{
    而(IsLocked(formXMLFilePath))Thread.sleep代码(100);    的FileStream文件=新的FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);    尝试{
        doc.Save(文件);
    } {最后
        file.Close();
    }
}

We have a website application which acts as a form designer.

The form data is stored in XML file. Each form has it's own xml file.

When i edit a form, i basically recreate the XML file.

public void Save(Guid form_Id, IEnumerable<FormData> formData)
{
    XDocument doc = new XDocument();
    XElement formsDataElement = new XElement("FormsData");
    doc.Add(formsDataElement);
    foreach (FormData data in formData)
    {
        formsDataElement.Add(new XElement("FormData",
                                 new XAttribute("Id", data.Id)
                                 new XAttribute("Name", data.Name)
                                 // other attributes
                             ));
    }

    doc.Save(formXMLFilePath);
}

This works good, but i want to make sure that two users won't update at the same time the XML file. I want to lock it somehow.

How can i individually lock the save process for each file?

I could lock the Save function like below, but this will lock all the users, even if they save a different XML file.

private static readonly object _lock = new object();
public void Save(Guid form_Id, IEnumerable<FormData> formData)
{
    lock(_lock)
    {
        XDocument doc = new XDocument();
        foreach (FormData data in formData)
        {
            // Code
        }

        doc.Save(formXMLFilePath);
    }
}

解决方案

Try something like this:

FileStream file = new FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);

try {
    doc.Save(file);
} finally {
    file.Close();
}

This uses a FileStream and we supply a FileShare mode. In our case we are exclusively locking the file so that only we can write to it.

However, this simply means that subsequent writes will fail as there is a lock.

To get around this problem I tend to have a queue and a separate thread who's only job is to process the queue and write to the file system.

However another solution is to simply try and access the file, and if that fails wait a little bit then try again. This would let you do something akin to lock where it waits until it can access and then proceeds:

private static bool IsLocked(string fileName)
{
    if (!File.Exists(fileName)) return false;

    try {
        FileStream file = new FileStream(fileName,FileMode.Open,FileAccess.Write,FileShare.None);

        try {
            return false;
        } finally {
            file.Close();
        }
    } catch (IOException) {
        return true;
    }
}

public void Save(Guid form_Id, IEnumerable<FormData> formData)
{
    while (IsLocked(formXMLFilePath)) Thread.Sleep(100);

    FileStream file = new FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);

    try {
        doc.Save(file);
    } finally {
        file.Close();
    }
}

这篇关于锁定XML文件中的Web应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆