C# 在Web应用程序中锁定XML文件
我们有一个网站应用程序,作为一个表单设计师 表单数据存储在XML文件中。每个表单都有自己的xml文件 当我编辑表单时,基本上是重新创建XML文件C# 在Web应用程序中锁定XML文件,c#,asp.net,locking,linq-to-xml,C#,Asp.net,Locking,Linq To Xml,我们有一个网站应用程序,作为一个表单设计师 表单数据存储在XML文件中。每个表单都有自己的xml文件 当我编辑表单时,基本上是重新创建XML文件 public void Save(Guid form_Id, IEnumerable<FormData> formData) { XDocument doc = new XDocument(); XElement formsDataElement = new XElement("FormsData"); doc.Ad
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);
}
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);
}
}
public void Save(Guid form\u Id,IEnumerable formData)
{
XDocument doc=新XDocument();
XElement formsDataElement=新XElement(“FormsData”);
单据新增(formsDataElement);
foreach(FormData中的FormData数据)
{
添加(新的XElement(“FormData”),
新XAttribute(“Id”,data.Id)
新XAttribute(“Name”,data.Name)
//其他属性
));
}
单据保存(formXMLFilePath);
}
这很好,但我想确保两个用户不会同时更新XML文件。我想把它锁起来
如何单独锁定每个文件的保存过程
我可以像下面那样锁定Save函数,但这将锁定所有用户,即使他们保存不同的XML文件
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);
}
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);
}
}
私有静态只读对象_lock=new object();
public void Save(Guid form\u Id,IEnumerable formData)
{
锁
{
XDocument doc=新XDocument();
foreach(FormData中的FormData数据)
{
//代码
}
单据保存(formXMLFilePath);
}
}
尝试以下方法:
FileStream file = new FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);
try {
doc.Save(file);
} finally {
file.Close();
}
这使用了FileStream
,我们提供了FileShare
模式。在我们的例子中,我们以独占方式锁定该文件,以便只有我们可以对其进行写入
然而,这仅仅意味着后续写入将失败,因为存在锁
为了解决这个问题,我倾向于使用一个队列和一个单独的线程,该线程的唯一任务是处理队列并写入文件系统
然而,另一种解决方案是尝试访问该文件,如果失败,请稍等片刻,然后重试。这将允许您执行类似于锁定的操作,在该操作中,它将等待,直到可以访问,然后继续:
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();
}
}
private static bool已锁定(字符串文件名)
{
如果(!File.Exists(fileName))返回false;
试一试{
FileStream file=newfilestream(文件名,FileMode.Open,FileAccess.Write,FileShare.None);
试一试{
返回false;
}最后{
file.Close();
}
}捕获(IOException){
返回true;
}
}
public void Save(Guid form\u Id,IEnumerable formData)
{
while(IsLocked(formXMLFilePath))Thread.Sleep(100);
FileStream file=newfilestream(formXMLFilePath,FileMode.Create,fileaclass.Write,FileShare.None);
试一试{
单据保存(文件);
}最后{
file.Close();
}
}
尝试以下方法:
FileStream file = new FileStream(formXMLFilePath,FileMode.Create,FileAccress.Write,FileShare.None);
try {
doc.Save(file);
} finally {
file.Close();
}
这使用了FileStream
,我们提供了FileShare
模式。在我们的例子中,我们以独占方式锁定该文件,以便只有我们可以对其进行写入
然而,这仅仅意味着后续写入将失败,因为存在锁
为了解决这个问题,我倾向于使用一个队列和一个单独的线程,该线程的唯一任务是处理队列并写入文件系统
然而,另一种解决方案是尝试访问该文件,如果失败,请稍等片刻,然后重试。这将允许您执行类似于锁定的操作,在该操作中,它将等待,直到可以访问,然后继续:
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();
}
}
private static bool已锁定(字符串文件名)
{
如果(!File.Exists(fileName))返回false;
试一试{
FileStream file=newfilestream(文件名,FileMode.Open,FileAccess.Write,FileShare.None);
试一试{
返回false;
}最后{
file.Close();
}
}捕获(IOException){
返回true;
}
}
public void Save(Guid form\u Id,IEnumerable formData)
{
while(IsLocked(formXMLFilePath))Thread.Sleep(100);
FileStream file=newfilestream(formXMLFilePath,FileMode.Create,fileaclass.Write,FileShare.None);
试一试{
单据保存(文件);
}最后{
file.Close();
}
}
打开xml文件后,您没有关闭xml文件连接。因此,我认为您需要在函数结束时首先关闭连接
你可以用这个
filename.Close();
我希望这将对您有所帮助您在打开xml文件后没有关闭xml文件连接。因此,我认为您需要在函数结束时首先关闭连接 你可以用这个
filename.Close();
我希望这将帮助您防止同时写入文件,
XDocument.Save
方法在内部使用以下构造函数创建一个FileStream
:
new FileStream(
outputFileName,
FileMode.Create,
FileAccess.Write,
FileShare.Read,
0x1000,
UseAsync)
选项FileShare.Read
可防止同时发生多个写操作。如果您试图同时执行两次写入,则会引发IOException
您可能需要编写一些代码来处理这种情况。这个答案应该准确地提供如何处理被锁定的文件,并在文件可用之前重新尝试
如果您的文档又小又多,您不应该经常遇到这种情况。为了防止同时写入文件,
XDocument.Save
方法在内部使用以下构造函数创建一个FileStream
:
new FileStream(
outputFileName,
FileMode.Create,
FileAccess.Write,
FileShare.Read,
0x1000,
UseAsync)
选项FileShare.Read
可防止同时发生多个写操作。如果您试图同时执行两次写入,则会引发IOException
您可能需要编写一些代码来处理这种情况。这个答案应该准确地提供如何处理被锁定的文件,并在文件可用之前重新尝试
如果您的文档又小又多,您不应该经常遇到这种情况(如果有的话)。您说的是“文件”。您是否将XML文档存储到Windows文件系统?是的,我将XML文件保存在硬盘上