我是网络编程的新手(Visual Web Developer中的C#),我的非C编程技巧也有点生疏。
我创建了一个表,其中一些单元格提示用户输入,一旦输入,输入将替换提示。因此,该表只能由第一个访问该页面的人注释。之后,需要为其他人提供带注释的页面以供查看,因此我需要在第一次完成后无需提示的情况下加载页面。要做到这一点,我(尝试)识别用户,以便该人获得可编辑页面,所有编辑都保存到xml文件,如果另一个用户运行页面,表设置将从xml文件中读回编辑。
我无法一直写入xml文件。具体来说,我似乎有时会创建多个访问该文件的进程,并在我的代码尝试更新时抛出运行时异常。
由于我不希望在每个页面加载时创建一个新文件,我认为静态类是可行的方法。这是代码:
static class XMLReaderWriter
{
static String fileLocation = "D:\\WebApp\\dashboard.xml";
static XMLReaderWriter()
{
FileStream fs = File.Create(fileLocation);
if (File.Exists(fileLocation))
{
// The opening tag
writeToFile(fileLocation, "<Dashboard>\n");
}
else
{
Exception e = new Exception("Failed to create " + fileLocation);
throw e;
}
}
public static void writeXML(String xml)
{
if(File.Exists(fileLocation))
{
writeToFile(fileLocation, xml);
}
else
{
File.Create(fileLocation);
writeToFile(fileLocation, xml);
}
}
private static void writeToFile(String fileLocation, String xml)
{
StreamWriter sw = new StreamWriter(fileLocation, true);
sw.WriteLine(xml);
sw.Close();
sw.Dispose();
}
public static string readXML(String trendID)
{
StringBuilder result = new StringBuilder("");
if (File.Exists(fileLocation))
{
XDocument xDoc = XDocument.Load(fileLocation);
var image = from id in xDoc.Descendants(trendID) select new
{
source = id.Attribute("image").Value
};
foreach (var imageSource in image)
{
result.AppendLine(imageSource.source);
}
}
return result.ToString();
}
public static void done()
{
// The closing tag
writeToFile(fileLocation, "</Dashboard>");
}
}
这是我调用方法的地方:
XMLReaderWriter.writeXML("\t<trend id=\"" + trendID +"\">\n\t\t" + innerHTML + "\" />\n\t</trend>");
最后有一个提交按钮,用于将结束标记添加到xml文件中:
<asp:Button runat="server" Text="Submit Changes" OnClick="Submit_Click" />
protected void Submit_Click(Object sender, EventArgs e)
{
XMLReaderWriter.done();
}
有时一切都运行得很好 - 虽然我似乎生成了格式错误的xml。但是大多数时候我会访问xml文件的过程不止一个。
感谢任何建议。
问候。
答案 0 :(得分:1)
Web编程意味着在多线程环境中工作。
从浏览器到Web服务器的每个请求都是一个单独的线程。
这就是为什么有时候你的文件无法被访问的原因,因为其他请求(比如 thread )可能会对其进行独占锁定。
另一点是使用语句应该是你的朋友,所以替换:
StreamWriter sw = new StreamWriter(fileLocation, true);
sw.WriteLine(xml);
sw.Close();
sw.Dispose();
... with:
using(StreamWriter sw = new StreamWriter(fileLocation, true))
{
sw.WriteLine(xml);
}
这相当于 try-finally 块,它为Dispose
的任何实现调用IDisposable
方法。因此,如果您的块失败,它将始终调用Dispose()
。
以上评论可以提一下,如果在一些线程中的某些操作出现问题时,对文件的锁将永远保留在其上,直到IIS应用程序停止或应用程序池被回收为止。
要点:
解决方案:从不使用Web应用程序中的文件,有更好的方法来保存数据:数据库 - 这些解决了并发场景中的许多问题! -