我被这个问题已头痛好久了,也请高手帮帮忙,
我想实现的效果是(论坛发言机制):
用户发言数据先写放入sql数据库,然后取出其id再和内容一并写入xml.写入数据库发多用户写入时应该没问题吧,可这写入xml是会乱的
我的代码如下:private static  XmlDocument doc;
private static object objectLock = new object(); 
public void insertxml(string filepath, string root, string _node, string str,string id)
        {
            XmlNode node;
            XmlElement xmlelem;
            lock (objectLock)
            {
                loadxml(filepath);
                node = doc.DocumentElement; //获取根节点
                  xmlelem = doc.CreateElement(_node);   //添加一个名为_node的子节点
                  xmlelem.InnerXml = str;//str如<id>1</id><name>a</name>
                node.AppendChild(xmlelem);                //结束此子节点   
                doc.DocumentElement.AppendChild(xmlelem); 
                savexml(filepath);
           }
        }

解决方案 »

  1.   

    这样做,你图的是什么呀?写入数据库然后再写到xml里边?
      

  2.   

    这样就是写入时执行数据库,再写到xml,以别人读时就不用数据库了,考虑的是减少服务器压力
      

  3.   

    每次访问缓存一分钟:
    response.cache.setExpires(DateTime.Now.AddSeconds(60));
    response.cache.setCacheability(HTTPcacheability.public);
    response.cache.setslidingExpiration(true);
      

  4.   

    cache["xx"] = xxx
    更多内容可以找些asp.net 缓存技术的资料看下
    学完了你会收获不小的.
      

  5.   

    可我觉得写入xml要比缓存好的多,还请老师们给我看看.
      

  6.   

    我想要实再的是用户如果只是浏览网页时就不必动用数据库了
    实现的只是html+js+xml
      

  7.   

    而这时aspx,ashx都用不上.所以缓存也就用不上了
      

  8.   

     lock (objectLock)
                {
    就可以了把
    还有可以定义一个全局变量,就像丢手绢似的,一次只有一个人拿到这个手绢。对于写入一个xml文件而言具体思路如下:
    论坛帖子id,这个帖子定义个全局变量isModify。
    我要修改这个帖子,先把这个帖子放入缓存isModify=true,其他用户浏览这个帖子先判断是否isModify 。是读取缓存版本。否有读xml,
    修改完毕 清除缓存 isModify=false。
      

  9.   

    或者不用缓存,ismodify=true可以访问数据库,读取数据库版本,否继续读取xml
    对于服务器而言,只有在修改数据时候负担会加重
      

  10.   

    xml是单发使用的,这东西无法并发!
    你看到的所谓并发实际上是操作系统的文件系统在使用互斥!
      

  11.   

    网站整站的缓存方式都是依靠的DataSet的ReadXml和WriteXml的方式实现的,这种方式在访问量不是很大的网站中是一点问题都没有的(最大可承受的日IP估计在8000-15000左右),但是当你的网站日IP访问量到达20000时,他就完全崩溃了,出现xml的并发占用问题日趋严重,于是我们就采用了文件流的形式去操作,具体代码如下:
    写入:
            Stream s = null;
            s = File.Open(FileName, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite);
            BinaryFormatter b = new BinaryFormatter();
            b.Serialize(s, ds);
            s.Close();
    读取:
            Stream s = null;
            s = File.Open(FileName, FileMode.Open, FileAccess.Read);
            BinaryFormatter b = new BinaryFormatter();
            ds = (DataSet)b.Deserialize(s);
            s.Close();
    这种方式在一定程度上解决了直接使用DataSet的ReadXml和WriteXml的方式带来的问题,但是当网站的日访问量达到40000或更高时,并发问题依然存在,其实存在并发的根本原因不是我们用了什么方式去读取或者写入(方式的不同的确在一定程度上可以解决一些问题,但根本原因没有得到根治),而是在两个或者更多个进程(有需要读取的也有需要写入的)在争抢同一个文件时程序如何给出一个可以让双方满意的方案,于是顺着这个思路,我有对程序做了以下改进:        //读取锁,可以让一个文件被多个进程同时读取,也可以保证只被一个进程改写
            ReaderWriterLock locker = new ReaderWriterLock();//读取锁()写入:
           Stream s = null;
           try
          {
              locker.AcquireWriterLock(1500);//写锁定(写入时间最大允许在1500毫秒内完成,超时就立即退出)
              if (!File.Exists(FileName))
              {
                    s = File.Create(FileName);
              }
              else
              {
                   //创建此文件的一个副本,以供同时访问此文件的读取进程使用(就像打印机的复制功能),由于使用了写锁定,其他的写入进程都将转化为读取进程,而读取进程是不存在并发问题的
                   File.Copy(FileName,FileName.Replace(".xml","Temp.xml"),true);
                   s = File.Open(FileName, FileMode.Create, FileAccess.ReadWrite,FileShare.ReadWrite);
              }
              BinaryFormatter b = new BinaryFormatter();
              b.Serialize(s, ds);
              s.Close();
           }
           finally
          {
              if(s!=null)
              {
                  s.Close();
              }
              locker.ReleaseWriterLock();//释放写锁定
              //这里可以加入删除临时文件的代码,但不建议这样做,我测试了下,会产生新的读写并发问题。
         }
    读取:
            Stream s = null;
            Stream sTemp = null;
            try
           {
                locker.AcquireReaderLock(1500);//读锁定(当所用文件被写锁定时超时时间为1500毫秒)
                s = File.Open(FileName, FileMode.Open, FileAccess.Read);
                BinaryFormatter b = new BinaryFormatter();
                ds = (DataSet)b.Deserialize(s);
                s.Close();
           }
           catch//这里使用catch主要是因为当读取方法所读的文件正在被改写时会获取空内容导致异常,或者写入超时导致文件内容出错时异常,或者读锁定超时后读取临时文件时刚好临时文件被删除时发生异常
           {
                locker.ReleaseReaderLock();//释放锁
                locker.AcquireReaderLock(1500);//再次锁定
               if(File.Exists(FileName.Replace(".xml","Temp.xml")))
               {
                     //读取副本文件
                     sTemp = File.Open(FileName.Replace(".xml","Temp.xml"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                     BinaryFormatter b = new BinaryFormatter();
                     ds = (DataSet)b.Deserialize(s);
                     sTemp.Close();
               }
           }
           finally
           {
               if(s!=null)
               {
                   s.Close();
               }
               if(sTemp!=null)
              {
                   sTemp.Close();
              }
              locker.ReleaseReaderLock();
          }
      

  12.   

    up,
    看来要写入xml只有规定符合条件时才能写入,也就是达到规定的条数才执行一次写入
    你们说了
      

  13.   

    loadxml(filepath);
    ======
    你是加载路径请使用load(filepath);
      

  14.   

    噢,我的loadxml()是我定义的函数,里面是load,谢谢楼上
      

  15.   

    upupupup
      

  16.   

    还用asp。net 的cache 吧
      

  17.   

    可我还是想用xml,这样服务器压力不大,成本不多.我的代码没有问题吧