Xml文件并发读写的解决方法

之前对xml的操作大都是通过XmlDocument对象来进行,但是这样的情况对于没有并发的是非常合适的,最近遇到了并发读写xml文件的情况。通过文件流来操作能解决大部分的并发情况,对于极端的情况会有问题。

测试方法:开两个线程读写同一个文件。主要是FileStream对象里面的三个参数FileMode,FileAccess,FileShared的枚举值选择。

class Program
{
private static string path = AppDomain.CurrentDomain.BaseDirectory + “cache.xml”;
static void Main(string[] args)
{
Thread th1 = new Thread(Writexml);
th1.Start();
Thread th2 = new Thread(Readxml);
th2.Start();

}

static void Writexml()
{
while (true)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format(“”, “aa”));
sb.AppendLine(String.Format(“”, “bb”));
sb.AppendLine(String.Format(“”, “{\”Value\”:[{\”BindingType\”:\”net.tcp\”,\”ServiceIP\”:\”192.168.1.226\”,\”ServicePort\”:\”9420\”,\”SvcPath\”:\”HotelPayNotifyService.svc\”}]}”));
sb.AppendLine(“”);
sb.AppendLine(“”);
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
fs.Write(bytes, 0, bytes.Length);
}
Thread.Sleep(200);
}
}

static void Readxml()
{
while (true)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
XmlDocument doc = new XmlDocument();
doc.Load(fs);
XmlNode dataNode = doc.SelectSingleNode(String.Format(“Cache/Subkey[@name='{0}’]/Data”, “bb”));
Console.WriteLine(dataNode.InnerText);
}
Thread.Sleep(100);
}
}

}

这样的情况还是比较正常,在几百毫秒的情况下,这样的能够满足大部分要求了。

另:还遇到了关于Dictionary并发的问题,声明了一个静态的Dictionary对象,通过深度复制来保证并发读写不会抛异常。处理的代码如下:

Dictionary<String, Dictionary<String, Object>> newdic = new Dictionary<string, Dictionary<string, object>>();

using (MemoryStream ms = new MemoryStream())
{
IFormatter formator = new BinaryFormatter();
formator.Serialize(ms, dic);
ms.Seek(0, SeekOrigin.Begin);
newdic=(formator.Deserialize(ms) as Dictionary<String,Dictionary<String,Object>>);
}

关于对象的复制可以参考这篇文章:浅复制(Shallow Copy)与深复制(Deep Copy)

上面是最近工作中遇到的问题,记录下方便以后查阅。

作者:张雪飞
出处:https://zhangxuefei.site/p/56
版权说明:欢迎转载,但必须注明出处,并在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

发表评论

电子邮件地址不会被公开。 必填项已用*标注