• 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("<Cache name="{0}">", "aa"));
                    sb.AppendLine(String.Format("<Subkey name="{0}">", "bb"));
                    sb.AppendLine(String.Format("<Data><![CDATA[{0}]]></Data>", "{"Value":[{"BindingType":"net.tcp","ServiceIP":"192.168.1.226","ServicePort":"9420","SvcPath":"HotelPayNotifyService.svc"}]}"));
                    sb.AppendLine("</Subkey>");
                    sb.AppendLine("</Cache>");
                    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)    

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

  • 相关阅读:
    窗口的基本手势事件处理
    用户自定义手势,并识别
    安卓程序国际化,手机屏幕适配器
    排序:冒泡,快排,归并。
    哈夫曼树学习
    二叉树的学习。
    ArrayList和vector的区别
    关于try-catch-finally return 的面试题
    Java中的抽象和封装
    关于SelectedValue的众多解决方案
  • 原文地址:https://www.cnblogs.com/mszhangxuefei/p/worknotes-8.html
Copyright © 2020-2023  润新知