C# windowsFORm 越跑越慢 ,求助!!!!高手

问题描述

privatevoidFileCopy(ObjectStates){stringhomedir=(string)States;string[]dirs=Directory.GetDirectories(homedir);Common.prgsBarTotal.Maximum=dirs.Length;Common.prgsBarTotal.Value=0;ThreadPool.SetMaxThreads(0,8);foreach(stringdirindirs){string[]files=Directory.GetFiles(dir);do{//thiscodeshouldbetestedfirstThreadPool.GetAvailableThreads(outa,outb);Thread.Sleep(517);ThreadPool.GetMaxThreads(outc,outd);}while(b!=d&&a!=c);iCount=0;Common.prgsBar.Value=0;Common.prgsBar.Maximum=files.Length;MaxCount=files.Length;Common.richTextBox.AppendText("切换文件夹:t"+dir+"n");if(files.Length==0){continue;}foreach(stringfileinfiles){//concretCopy(file);//ThreadPool.RegisterWaitForSingleObject(eventP,newWaitCallback(concretCopy),file,1000,true);ThreadPool.QueueUserWorkItem(newWaitCallback(concretCopy),file);}Common.prgsBarTotal.Value+=Common.prgsBarTotal.Step;//eventX.Reset();eventX.WaitOne();eventX.Reset();GC.Collect();}/*stringdir=(string)States;string[]files=Directory.GetFiles(dir);eventX.Reset();iCount=0;Common.prgsBar.Value=0;Common.prgsBar.Maximum=files.Length;MaxCount=files.Length;foreach(stringfileinfiles){ThreadPool.SetMaxThreads(1,1);ThreadPool.QueueUserWorkItem(newWaitCallback(concretCopy),file);}Common.prgsBarTotal.Value+=Common.prgsBarTotal.Step;eventX.WaitOne();eventX.Reset();GC.Collect();string[]dirs=Directory.GetDirectories(dir);foreach(stringdindirs){FileCopy(d);Common.richTextBox.AppendText("切换文件夹n");}**/}privatevoidconcretCopy(ObjectState){//inta=Common.prgsBar.Value;stringfile=(string)State;lock(Common.o){Common.prgsBar.Value+=Common.prgsBar.Step;Common.richTextBox.AppendText(DateTime.Now+"t"+Thread.CurrentThread.ManagedThreadId+"t"+file+"thavecheckedn");}if(file.ToLower().EndsWith(".json".ToLower())){//todo:打开文件,检验其中的内容,是不是我要的uri,如果是的话,关闭//这个文件流,把这个文件和对应的csv文件,复制到目标文件夹。stringline=readFile(file);stringuri=getURI(line);stringtar;if(checkURI(uri,outtar)){list.Clear();Common.getJSON(line,list,1);FileInfofileinfo=newFileInfo(file);stringdes=Common.outputDir+"\"+tar.Replace("/","").Replace(":","");Common.getValueByName("filename",list,refwebvalues);Common.getValueByName("csvname",list,refcsvnames);Common.getValueByName("language",list,reflanguage);stringroot=fileinfo.DirectoryName;foreach(stringwebvalueinwebvalues){if(File.Exists(fileinfo.DirectoryName+"\"+webvalue)){File.Copy(fileinfo.DirectoryName+"\"+webvalue,des+"\"+webvalue,true);}else{log.Log("**********************=========newweboccur========********************");log.Log(DateTime.Now+"t"+file);log.Log(DateTime.Now+"t"+fileinfo.DirectoryName+"\"+webvalue+"notexistn");}}foreach(stringcsvnameincsvnames){if(File.Exists(fileinfo.DirectoryName+"\"+csvname)){File.Copy(fileinfo.DirectoryName+"\"+csvname,des+"\"+csvname,true);}else{log.Log("**********************==========newcsvoccur============********************");log.Log(DateTime.Now+"t"+file);log.Log(DateTime.Now+"t"+fileinfo.DirectoryName+"\"+csvname+"notexistn");}}File.Copy(file,des+"\"+fileinfo.Name,true);}}Interlocked.Increment(refiCount);if(iCount>=MaxCount){eventX.Set();}}

调用的顺序就是从FileCopy到concreteCopy,为什么,当在含有50w个文件夹中,执行的时候,会越来越慢,本人菜鸟,求教育,求指点。

解决方案

解决方案二:
你看看你的内存是不是占用很多,内存得不到及时释放频繁调用GC.Collect();看看是不是有可以复用的方法,比如开缓存等,另外线程不要太多
解决方案三:
内存的情况是这样的,30+,60+,110+,150+这样循环着跳,另外,没有开太多线程,就开了一个线程池,没有别的线程了,list也每次都清理了,不是递增的。实在想不明白了
解决方案四:
引用1楼bdmh的回复:

你看看你的内存是不是占用很多,内存得不到及时释放频繁调用GC.Collect();看看是不是有可以复用的方法,比如开缓存等,另外线程不要太多

内存的情况是这样的,30+,60+,110+,150+这样循环着跳,另外,没有开太多线程,就开了一个线程池,没有别的线程了,list也每次都清理了,不是递增的。我实在想不明白了
解决方案五:
程序比较乱,有些代码也不知道是干什么的,随便说几点:在工作程序中,访问UI组件,使用BeginInvoke,不要同步阻塞地去Invoke,也不要有不必要的lock语句。否则你的线程也没有多大意义。你的程序“看上去越跑越慢”是正常的。因为你的更新进度条的语句是在线程执行程序的“开头”而不是“结尾”。ThreadPool会自动根据最合理的情况来延迟、批量启动线程,不会一下子启动所有线程。如果一下子并发执行所有线程(假设可能的话),你会一下子就看到进度条跑到100%了,然后就是一直在等待。而现在ThreadPool只会逐步启动批量线程,所以你看到的不是一下子跑到100%。如果你把更新进度条的语句挪到concretCopy方法的最后去,你就不会被一开始的那种假想所迷惑了。不用调用GC。它不会让你的程序变快的。你这里并没有“大规模申请内存、然后一直不释放,最后一瞬间才突然释放几百兆内存”的情况。你的程序的concretCopy执行完,局部变量就会自动被GC释放。用代码调用GC通常只会让程序更慢(但是影响很小),总之不会更快的。
解决方案六:
引用4楼sp1234的回复:

程序比较乱,有些代码也不知道是干什么的,随便说几点:在工作程序中,访问UI组件,使用BeginInvoke,不要同步阻塞地去Invoke,也不要有不必要的lock语句。否则你的线程也没有多大意义。你的程序“看上去越跑越慢”是正常的。因为你的更新进度条的语句是在线程执行程序的“开头”而不是“结尾”。ThreadPool会自动根据最合理的情况来延迟、批量启动线程,不会一下子启动所有线程。如果一下子并发执行所有线程(假设可能的话),你会一下子就看到进度条跑到100%了,然后就是一直在等待。而现在ThreadPool只会逐步启动批量线程,所以你看到的不是一下子跑到100%。如果你把更新进度条的语句挪到concretCopy方法的最后去,你就不会被一开始的那种假想所迷惑了。不用调用GC。它不会让你的程序变快的。你这里并没有“大规模申请内存、然后一直不释放,最后一瞬间才突然释放几百兆内存”的情况。你的程序的concretCopy执行完,局部变量就会自动被GC释放。用代码调用GC通常只会让程序更慢(但是影响很小),总之不会更快的。

进度条不是我关注的重点,现在的问题就是,在50万个文件的文件夹下跑的话,跑过一天以后,程序会很慢,但是刚开始的时候很快的,还有一个问题就是,内存是30+、60+、80+、112、150,这样循环的跳,不知道这个能说明什么问题。list是clear的,并没有递增,Json是结构体,并不是类
解决方案七:
用线程池执行copy没什么意义磁盘比起CPU是很慢的你CPU开那么多线程,似乎可以跑的飞快,但是其实到磁盘那里,还是得一点一点的写入文件你不如改成顺序执行,而不是并发执行
解决方案八:
至于说你的do{}while循环,你又要设置ThreadPool.SetMaxThreads(0,8),又要循环等待人家.netframework一个线程都不占用的时候才继续执行for循环。是不是你想“控制”的太多了。删除这两块代码,会更好。不要去设置系统线程池大小(虽然在.net4.0下,即使你设置了,可能也还是会使用1000~60000多个,而不是你设置的8)。也不要写下面的循环语句。线程池会自动优化,不是等到b!=d&&a!=c条件才可以继续跑的。总的来说,线程虽然会让你的程序的每一个concretCopy看起来变慢,比如说并发3个线程是1秒做完一个任务,并发20个线程时是10秒做完一个任务,并发50个线程时是30秒做完一个任务,但是总的执行时间反而缩短了。并发时,每一个任务的执行时间可能变慢到原来的200倍,但是总的执行时间却缩短到原来的10分之一。所以如果你想一下子就看到每一个任务的执行时间没有缩短,就不要并发。并发必定是让每一个任务都牺牲速度,来获取总的任务更快执行完毕的。
解决方案九:
如果你想一下子就看到每一个任务的执行时间没有缩短-->如果你想一下子就看到每一个任务的执行时间没有延长当有一堆不同类型的操作时,并发确实可以避免CPU空闲时别的任务也得不到执行。但是当你有一堆完全一样的任务,那么并发时你肯定看到每一个任务的执行时间都大大延长了,只不过总的完成时间缩短了而已。
解决方案十:
引用6楼Z65443344的回复:

用线程池执行copy没什么意义磁盘比起CPU是很慢的你CPU开那么多线程,似乎可以跑的飞快,但是其实到磁盘那里,还是得一点一点的写入文件你不如改成顺序执行,而不是并发执行

是这样的,您说的顺序执行的我也试了,到最后界面都卡顿了,但是在程序刚打开的一瞬间,刷刷的,那速度,为什么后来就惨不忍睹了。
解决方案十一:
因为你用了Common.richTextBox.AppendText控件里内容多了之后,刷新必然变慢,你只往里不断添加文本,而从来不清除过期数据
解决方案十二:
引用8楼sp1234的回复:

如果你想一下子就看到每一个任务的执行时间没有缩短-->如果你想一下子就看到每一个任务的执行时间没有延长当有一堆不同类型的操作时,并发确实可以避免CPU空闲时别的任务也得不到执行。但是当你有一堆完全一样的任务,那么并发时你肯定看到每一个任务的执行时间都大大延长了,只不过总的完成时间缩短了而已。

其实我也没有针对单个任务,快慢的比较是说,在刚开始执行程序的时候,和执行了很长一段时间以后,这两个时间点进行比较,相同的代码为什么随着时间的推移,越来越慢呢
解决方案十三:
引用10楼Z65443344的回复:

因为你用了Common.richTextBox.AppendText控件里内容多了之后,刷新必然变慢,你只往里不断添加文本,而从来不清除过期数据

这个有道理,我去试试:),thx
解决方案十四:
把所有结果都放到richTextBox里显示不仅内存越占越多,而且随着内容增多,刷新也会越来越慢毕竟它是带自动滚动条的,要计算里面的行数,要根据行数来计算滚动条拖块的高度,要绘制文字,绘制滚动条
解决方案十五:
引用11楼n2202666的回复:

其实我也没有针对单个任务,快慢的比较是说,在刚开始执行程序的时候,和执行了很长一段时间以后,这两个时间点进行比较,相同的代码为什么随着时间的推移,越来越慢呢

你应该等到线程数达到最大值并且不再增加时,再开始观察执行速度。
其他方案:
引用12楼n2202666的回复:

Quote: 引用10楼Z65443344的回复:
因为你用了Common.richTextBox.AppendText控件里内容多了之后,刷新必然变慢,你只往里不断添加文本,而从来不清除过期数据

这个有道理,我去试试:),thx

你的FileCopy本身就不应该放在主线程里执行,它受UI刷新速度越来越慢的影响。你的程序中有直接卡死在UI控件上的代码,而且还有lock语句(语句中需要等待界面UI同步处理结束才能继续执行)。
其他方案:
引用13楼Z65443344的回复:

把所有结果都放到richTextBox里显示不仅内存越占越多,而且随着内容增多,刷新也会越来越慢毕竟它是带自动滚动条的,要计算里面的行数,要根据行数来计算滚动条拖块的高度,要绘制文字,绘制滚动条

大神,我爱你,我们交个朋友吧,clear以后,我发现我的世界瞬间就干净了,有你真好,QQ527573638,真心求交友
其他方案:
如果没有“阻塞式”的代码(访问UI控件、lock、无端地搞循环语句,这些都是阻塞自己的),即使你往主线程的UI上去Append一些内容,如果你的机器的CPU不是持续跑满95%以上的,那么你的多线程处理程序的进度也应该是保持平稳的。应该把跨线程阻塞的语句尽可能全都改掉。
其他方案:
引用17楼sp1234的回复:

如果没有“阻塞式”的代码(访问UI控件、lock、无端地搞循环语句,这些都是阻塞自己的),即使你往主线程的UI上去Append一些内容,如果你的机器的CPU不是持续跑满95%以上的,那么你的多线程处理程序的进度也应该是保持平稳的。应该把跨线程阻塞的语句尽可能全都改掉。

恩,我理解你的意思,你对多线程学的很透彻,可能是我没有把代码全贴出来,那些阻塞的不能去掉,那是逻辑的代码,去掉以后,整个程序就坏了,,谢谢你的帮助

时间: 2024-10-27 14:58:04

C# windowsFORm 越跑越慢 ,求助!!!!高手的相关文章

流量计费是糊涂账?揭开“流量越跑越快”真相

虽然数次天价流量事件最终都被证明为乌龙,且运营商三番五次站出来表明自己的清白,但消费者仍用习惯性质疑的眼光审视运营商的流量计费可靠性. 如果今天,你在马路上拦下一位路人问:"电信运营商偷跑流量,你信吗?" 也许这位路人会略带讽刺意味地回答你:"不管你信不信,反正我是信了!" 这个笑话反映了运营商在舆论大环境中的窘境.最近一个月,用户对于流量越跑越快的质疑声浪越来越高,运营商又一次成为了舆论的焦点和争议的中心. 虽然数次天价流量事件最终都被证明为乌龙,且运营商三番五次

徐立:1200层神经网络夺冠ImageNet,深度学习越深越好?| 新智元 AI 领军人物专访

人工智能领域的创业浪潮中,计算机视觉技术(CV)可以说是一个较为火热的方向,呈遍地开花之势.在这片江湖中,有四家公司特别突出,有 CV 领域的"一桶筐汤" 之称,可以看成是具有巨大潜力的"四小龙". 其中,"汤"在这里指的就是创建于2014年的商汤科技开发有限公司.其他三家"一"指创立于2016年的依图科技."桶"指的是2014年的"格灵深瞳","筐"指的是成立于20

SSD固态硬盘怎么优化 固态硬盘越用越慢怎么办?

  SSD固态硬盘怎么优化   固态硬盘越用越慢怎么办?           今天本文主要与大家介绍下SSD固态硬盘优化的一些知识,主要是面向经常有一些网友称自己购买的固态硬盘速度不是很快,或者说感觉不到SSD与传统HDD硬盘差距的朋友看. SSD固态硬盘优化指南 由于传统的HDD硬盘速度其实也并不慢,因为在一般应用方面我们很难感受到速度差距,不过我们可以在开机时间.大型应用载入以及文件传输方面感受到SSD固态硬盘的高速体验,不过并不是购买了固态硬盘就可以体验其最高读取传输速度,这里还会涉及到很

一旦发现领域已经在走下坡路了,这个领域路越走越窄的时候,我们要坚定地走出去,不能做鸵鸟,把头埋在沙子里

本文作者将从自己的工作经历出发,从工程师择业的角度,与观众产生共鸣,从大公司到创业公司,需要转变的思路与做事情的方法,有原则性的东西,也有真实案例与身边的故事,还会穿插一些工程师的软技能.    注:本文整理自云极星创联合创始人兼 CTO 刘世民在 QCon 北京 2017 上的演讲,原题为<从大公司到创业公司>.   写在前面 不想当将军的士兵不是好士兵,不想做 CTO 的技术人不是好技术人 刚拿到这个话题的时候,提笔不知道要写什么.大约三个月之前,有记者对我做过一个专访,之后在官网首页发布

越绿越赚钱

文/王延春 互联网引领经济的时代过去了,金融引领经济的时代过去了,那么下一个引领经济的是谁?--低碳经济.这种认识像一种气味在各国蔓延,如果说,"低碳经济"曾是一句口号,那么金融危机的爆发促使它正在变成行动,依托石油.天然气的"高碳经济"已面临衰退,选择"低碳生活方式",进行"低碳消费"已成为当下时髦的话题.而寻找"低碳经济"的商机正成为企业家的新思维--"越绿色越赚钱." <20

Google让我们越变越傻

Google让我们越变越傻 网络新阅读方式: 海量浏览 卡尔不是唯一一个遇到此种问题的人.长期在密歇根医学院任教的布鲁斯·弗里德曼,今年早些时候也在自己的blog上写到互联网如何改变了他的思维习惯."现在我已几乎完全丧失了阅读稍长些文章的能力,不管是在网上,还是在纸上."他在电话里告诉卡尔,他的思维呈现出一种"碎读"特性,源自上网快速浏览多方短文的习惯."我再也读不了<战争与和平>了."弗里德曼承认,"我失去了这个本事.即便

流量不清零:为何让三运营商的垄断越走越紧

         移动.联通.电信,三大运营商的一举一动都牵动着亿万消费者的心--当下绝大部分国人的生活都离不开运营商的语音通话.短信.流量及其他增值.延展服务.但多年以来,三大运营商始终处于垄断地位."一言堂"式的管理.运营模式,让它们饱受用户批评,却依然没有取得质的进步.而在政府开始对运营商"动刀"之后,才开始有了新的变化. 其中,最主要的举措就是资费降低及流量不清零等.但运营商推出的多种举措更像是"应付公事",远未达到用户心中的理想效果.而

春晚互联网投放广告,营销大战越大越热

到现在你在春晚上看到几家互联网公司广告了? 互联网公司在春节投放广告已经不是什么新鲜事.2015年羊年春晚,大家看广告抢红包抢到手软,不过貌似几块的小红包已经让很多人索然无味,仅凭互动已经很难取悦用户了. 但春节营销还必须做.毕竟对于中国人来说,春节是最重要的年度节日,此时给用户留下印象,很容易畅快一整年.而且大量熟练的互联网用户会进行迁移,那时他们就成了免费的布道师. 何况对于互联网公司来说,春节营销还有另一番意义.那些有钱在传统媒体上大量投放广告的,大多是用户量过亿的大公司,从一线城市下沉,

深圳房价大步跨入2万元时代豪宅越贵越好卖

在2007年10月之后,深圳房价整体下跌超过30%,大批炒房客被套牢.但如今,深圳却再度成为新一轮楼价上涨的领跑者. 统计资料显示,今年9月,深圳新房成交均价达到创纪录的20940元/m2,较2月份10770元/m2的低点上涨了94%,7个月内房价几近翻番.进入10月,深圳市新建商品住宅销售均价为20234元/m2,虽然比9月下降了3.37%,但比去年同期依然上涨了59.25%.而此前,深圳房价的历史最高位是2007年10月的17350元/m2.这意味着,目前深圳的房价已经跃过了2007年房价的