一个设计到IO和XML的程序,为什么随着执行次数的增加,
执行速度为也逐渐加长呢?内存占用也在逐渐增大!程序主要功能就是对csproj里记录的文件里的content和None见进行列表,并记录文件大小在不关闭程序的情况下执行速度如下:
第一次: 85823408 
第二次: 217112192 
第三次: 357614224 
第四次: 511936128 
第五次: 629905760 
第六次: 760994256 
第七次: 910809680 到后来速度简直慢到无法容忍的地步!
将近一秒钟才读到一个文件程序如下: private ArrayList fiAL = new ArrayList();
private long TotalSize = 0; string BuildAction = "|Content|None|";
string Path = string.Empty ;
string DrctPath = string.Empty ;
private void getCsprojPathBTN_Click(object sender, System.EventArgs e)
{ openCsprojFileDialog.ShowDialog();
csprojPathTxt.Text = openCsprojFileDialog.FileName; Path = csprojPathTxt.Text ;
DrctPath = Path.Substring( 0 , Path.LastIndexOf("\\") + 1 ); Thread thread = new Thread ( new ThreadStart (getAllFiles));
thread.Start();

} private void getAllFiles( )
{
long startTime = DateTime.Now.Ticks;
long endTime = 0;
string csprojPath = csprojPathTxt.Text;
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"gb2312\"?> \n ");

Encoding ec = Encoding.GetEncoding("gb2312");
using ( StreamReader sr = new StreamReader( csprojPath , ec ) ) 
{
string line;

while ((line = sr.ReadLine()) != null) 
{
sb.Append( line );
}
} XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml( sb.ToString() ); XmlNode node = xmlDoc.SelectSingleNode("//Files").FirstChild;
string filePath = string.Empty;
FileInfo fi = null ; for ( int i = 0 ; i < node.ChildNodes.Count ; i ++ )
{
if ( node.ChildNodes[i].Attributes["BuildAction"] != null )
{
if ( BuildAction.IndexOf( "|" + node.ChildNodes[i].Attributes["BuildAction"].Value + "|") != -1 )
{
filePath = DrctPath + node.ChildNodes[i].Attributes["RelPath"].Value;
writeLine( filePath );
fi = new FileInfo( filePath ); fileInfo myfi = new fileInfo( filePath , fi.Length );
fiAL.Add( myfi );
TotalSize += myfi.fileSize;
}
}
} endTime = DateTime.Now.Ticks; writeLine( ( endTime - startTime ).ToString() );

fi = null;
node = null;
xmlDoc = null;
sb = null; pBar.Minimum = 0 ;
pBar.Maximum = Convert.ToInt32( TotalSize ); writeLine( "提取完成!" ); Thread.CurrentThread.Abort();
Thread.CurrentThread.Join();
return ;
} private void writeLine( string str )
{
infoListTxt.Text += str + " \r\n "; //使滚动条滚动到最后
this.infoListTxt.Focus();
this.infoListTxt.Select(infoListTxt.TextLength,0);
this.infoListTxt.ScrollToCaret();
}
         //增加定义的文件结构,记录文件的路径和大小,为以后copy的时候显示进度
public struct fileInfo
{
public string fileFullPath;
public long fileSize; public fileInfo( string ffp , long fz )
{
fileFullPath = ffp;
fileSize = fz;
}

}

解决方案 »

  1.   

    会不会是Thread没有真的释放掉?
      

  2.   

    Thread.CurrentThread.Join();
    这句话应该是有问题的
    Join()函数的作用是这样的:假如我在代码中调用了t1.Join(),当前线程就会挂起,一直到t1线程结束才继续运行在
    t1.Join();
    Console.Write("aaa");
    这样一段代码中,程序会在t1结束后再输出"aaa"可见
    Thread.CurrentThread.Join();
    是一句很矛盾的话,当前线程 等待 当前线程结束后 再继续运行???另外,线程结束的时候不需要Tread.CurrentThread.Abort(),线程函数return后,线程就结束了
      

  3.   

    看了一下代码,有几个不明白的地方:
    1、读取一个文件这么简单的操作,没有必要起一个thread吧。
    2、还有读XML文件时,可以直接用XML的LOAD的方法,为什么要循环?
    3、fi = null;并不是关闭文件。
    4、StringBuilder sb ,Sb变量里的文本不能太长了,要么操作会很慢了。
    5、node.ChildNodes[i].Attributes["BuildAction"] != null ,这种用法极不可取,要用xpath,就快得一塌糊涂。
      

  4.   

    to 
    Thread.CurrentThread.Abort();
    Thread.CurrentThread.Join();这两句没什么意思,去掉。
    至于资源上涨,最好看看什么资源没有显示关闭。
      

  5.   

    imdg(imdg) ( ) 信誉:100    Blog 
    ----------------------------------
    谢谢你的解释,通俗易懂,受益匪浅~~
    sweeperch() ( ) 信誉:100    Blog  2006-09-01 11:37:00  得分: 0   
       看了一下代码,有几个不明白的地方:
    1、读取一个文件这么简单的操作,没有必要起一个thread吧。
    --------------------------------------------------------------
    我在读取文件的同时,希望看到我的程序正在处理那个文件,所以用了线程~
    2、还有读XML文件时,可以直接用XML的LOAD的方法,为什么要循环?
    ----------------------------------------------------------------
    因为csproj文件不是标准的xml格式,所以需要在文件头部分添加一行这样的东西
    <?xml version="1.0" encoding="gb2312"?> 
    本来想用流的方式在前面添加这个东西,但没有找到可行的方法~
    所以只能用StringBuilder重新组建一个新串~3、fi = null;并不是关闭文件。
    -------------------------------------------------------------
    本来是没有这句的,是因为发现程序越运行越慢,所以加上试试的~4、StringBuilder sb ,Sb变量里的文本不能太长了,要么操作会很慢了。
    ---------------------------------------------------------------------
    好像只有用它哦~我看《C#字符串和正则表达式参考手册》里面,
    说如果频繁操作一个字符串,还是建议使用它的,
    因为它是在原来内存的基础上扩充内存,
    如果超过了最大字符数(Capacity),好像就会扩充为 Capacity * 2 ...
    5、node.ChildNodes[i].Attributes["BuildAction"] != null ,这种用法极不可取,要用xpath,就快得一塌糊涂。
    -------------------------------------------------------------------------------
    因为csproj的格式问题,有的节点没有BuildAction属性~
    Knight94(愚翁) ( ) 信誉:110    Blog 
    ----------------------------------------------------------
    是哦~就是不知道怎么释放资源哦~
    如果有时间、有兴趣的话,可以看一下我的源码:
    http://www.jpsoft.com.cn/GetProjectFiles.rar  
     
      

  6.   

    change
    using ( StreamReader sr = new StreamReader( csprojPath , ec ) )
    {
    string line;while ((line = sr.ReadLine()) != null)
    {
    sb.Append( line );
    }
    }with
    using ( StreamReader sr = new StreamReader( csprojPath , ec ) )
    {
    while ( sr.Peek() >= 0)
    {
    sb.Append( sr.ReadLine() );
    }
    }
      

  7.   

    要么你在开启线程之前显式调用GC.Collect(),看看效果如何。
      

  8.   

    这样:.....GC.Collect();
    Thread thread = new Thread ( new ThreadStart (getAllFiles));
    thread.Start();
    ......或这样:private void getAllFiles( )
    {
    GC.Collect();
             ...
    while ( sr.Peek() >= 0)
    {
         sb.Append( sr.ReadLine() );
    }也换了~
    555555555555555555,都没有效果哦~我还发现一个规律:
    内存的增长和运行速度的增长不成比例!
    运行速度每执行一此,必定会增长一定的数量~就是说越来越慢~~~~
    但内存占用不同,有是执行下来一点长一点,
    而有时又减一点,但从总体趋势可以看出它还是在增加~
      

  9.   

    to 但内存占用不同,有是执行下来一点长一点,
    而有时又减一点,但从总体趋势可以看出它还是在增加~如果什么都不运行的话,是否还上涨呢GC回收内存是不可控的,所以有时产生的现象就如你所说的那样。
      

  10.   

    开始 12192k
     7210368 18848k
     7510800 20036k
     10515120 20424k
     14020160 20668k
     16423616 20852k
     19928656 21120k
     23033120 21200k
     26538160 21704k
     29642624 21760k
     33147664 25532k
     36552560 24024k
     38655584 25588k
     42761488 25436k
     47167824 28308k
      

  11.   

    你是否可以把你的操作减少些,
    例如
    不用通过stringbuilder做一次倒手,直接通过stream,然后用XmlDocument.Load方法来加载,这样是否好些呢。
      

  12.   

    楼主啊.要不是我机器没有办法调试,我帮你重写一下.我们公司的代码生成器都是我写的,所有C#的代码文件和工程文件完全可以直接用xml来操作.没有发现有什么慢的地方.
      

  13.   

    问题已经找到了~
    速度慢的根源是这里:
    writeLine( filePath );因为:没找到一个文件都会对textbox进行一次输出操作
    private void writeLine( string str )
    {
    infoListTxt.Text += str + " \r\n "; //使滚动条滚动到最后
    this.infoListTxt.Focus();
    this.infoListTxt.Select(infoListTxt.TextLength,0);
    this.infoListTxt.ScrollToCaret();
    }每执行一句:
    infoListTxt.Text += str + " \r\n ";
    都会创建一个新字符串,然后赋值给TextBox的Text属性,
    随着执行次数的增加,这个新字符串就会非常的大了,所以速度就会越来越慢了,
    当把那个输出文件名的那行代码注释掉后,执行十次,每一次的速度都是差不多的了~
    但又有个问题了:
    我又看不见程序执行的进度了~也不能记录到底找到了多少文件了~
      

  14.   

    开贴再议:
    http://community.csdn.net/Expert/topic/4995/4995165.xml?temp=.6057855