应为关系到公司的极目,恕不放出具体代码了
项目的主要目的是从其他来源提供的.DBF文件(对方是手写的,无法用其他工具打开,只能用二进制流读取)中将数据读出后按照我们需要的格式写入分类.TXT文件中,
数据纪录固定2000行,每行的长度相同,数据总起始点相同.文件更新频率为1分钟20次,平均3秒1次,间隔不固定.文件大小在1M左右
现在DEMO写出来了,运行正常,目的也达到了,可是存在下面的问题
方法1:从文件中循环读取每条纪录,格式化,写入想对应的.TXT,线程休眠(Thread.Sleep(1);)继续;
问题:CPU占用50%上下,但是整个处理过程完成需要大概6~7秒;格式化所用的语句已经精简到最低限度
方法2:监控.DBF,当文件最后修噶日期变动时抛出线程,做个上面一样的事;
问题:一样的问题,处理时间过长,造成数据丢失.而且,当有多条线呈并存时会出现文件写冲突
方法3:做的事同1,不进行休眠
问题,处理时间虽然缩短了(2秒上下),但是CPU占用撑顶....老板看了DEMO命令必须要把CPU占用压缩到30%以下~~~个位大大有没有什么好的优化方案啊~~~~
Thread.Sleep是肯定用不了了....T-T`~~~~

解决方案 »

  1.   

    1:不要使用线程的Sleep,因为 这个方法会导致线程的切换,而造成实际的延时大于你指定的1ms,可以使用:
    Thread.SpinWait(1000);  //这个数字可以自己调整,它大体类似于执行:
    for(int i=0;i<1000;i++)
    {
       //
    }
    在整个过程中没有线程的上下文切换,可以节约时间提高效率。2:多文件之间的读取和写入的同步有问题,请仔细检查、优化、同步方案。
      

  2.   

    感觉你的程序IO为主,逻辑也不会超级复杂,不应该占用这么多CPU,估计还是代码有问题,因为涉及字符串处理,突然想到以前有人提过字符串处理很慢的问题,主要问题是C#中经常变化的字符串要用stringbuilder,不要用string,不知道你是不是也有这个问题,动态变化频繁的字符串,使用string和stringbuilder会有非常大的效率差别。
      

  3.   

    1、字符串分析处理问题。用比较好的分析处理算法,至少应该用StringBuilder。
    2、写入数据的时候不要用线程,合理处理好IO方面的操作。
      

  4.   

    关于这种定时任务我用开源的quartz.net框架来做效率都还好,还没仔细看过源码,自己做的时候各种资源都占用的比较多。
      

  5.   

    看起来时间主要耗费在格式化上面了,否则CPU不可能占用那么多。
    从循环次数来看,每次格式化花的时间太多,必须在这方面花功夫。把格式化的输入、输出要求晒出来看看。
      

  6.   

    数据源是定长的二进制六作为一条数据,每条数据包含30个字段(.dbf文件)
    我要格式化成字段标志+值+,的方式,比如Name字段,值为111的纪录就变成 N111,.....等等,现在我已经把着部分写死,虽然格式化部分的效率好点了,可是总体还是没什么差别关于StringBuilder,是能稍微提供下资料呢?虽然我可以去参考MSDN,可不我怕看不懂Thread.SpinWait我也去看看
      

  7.   

    MSDN里边关于String有如下说明:
    String 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。如果需要修改字符串对象的实际内容,请使用 System.Text.StringBuilder 类。
      

  8.   

    不要用sheep,可以用Join另外sheep(1)会导致线程的切换的说法.我有些不赞同,如果是sheep(0)的话.可能会切换而且sheep(n)这个n在实际的执行中可能不会是你想要的n,可能时间会长
    总之用去sheep(n)方法的程序设计也是什么好设计,可以说是个比较烂的设计改成join试一下吧.
      

  9.   

    总之用sheep(n)方法的程序设计不是什么好设计,可以说是个比较烂的设计
      

  10.   

    join 是阻塞到某个线程结束吧
    我只是想让监控线程休眠1秒(n=1000)
    Thread.SpinWait 我去试过了,CPU没下去,在只开1条监控线程的情况下,用sleep(1000)能确实的把CPU放到2%一下,但是用Thread.SpinWait(1000),CPU就下不去.......还有,关于流文件的逐行扫描MemoryStream FS = new MemoryStream(File.ReadAllBytes(FilePath));
    FS.Seek(0,SeekOrigin.Begin);
    byte[] Data =new byte[256];
    while(FS.Position < FS.Length)
    {
    FS.Read(Data,0,256);
    }就算单纯的读(循环一般在2000次左右),也会在读的瞬间(1秒以下)CPU占用飚到100%
    如果用sleep(1)暂停的话CPU是能下来,可是处理时间就要超过3秒......
    这部分有没有什么好的优化方案?
      

  11.   

    一次性读取文件,完成以后,也就是数据进入内存,此时,读取文件的线程或者什么的,可以停止掉,然后处理数据,数据处理的时候每次sleep 1毫秒,应该就不会让cpu占用过高了,但是有个问题是,一般服务器都是志强的双cpu的 你的进程基本不会超过50%的占用率的,即使按照你的写法也不会的,再加上现在的机器都是双核的,很难碰到你说的问题的
      

  12.   

    想到个事
    加入有这样2个文件
    文件1的格式是没6和BYTE为一个字段,每行20个字段,文件总行数固定为2000
    文件2格式为1BYTE标志符+14BYTE数据+,(逗号) ,同样每行 20字段,2000行
    有没有什么办法又快CPU消耗又小的将文件1格式格式化成文件2的格式
    2000行数据的扫描循环是没办法避免了,20个字段我是用array.copy的方式放到定义好的行BYTE[]里去的,可是CPU占用还是很高...
      

  13.   


    可是确实是90%以上的占用(还是双核同时90%以上....)
    读取文件的线程是不能停掉的,这个线程是一直在循环的,工作流程是这样的
    开始->指定的文件是否变动 -> 没变动 -> 什么都不做 -> sleep(1000)
                          -> 变动   -> 抛出委托   -> sleep(1000)
    <-----------------------------------------------------------就这样一直在循环的,只开这线程的情况下CPU占用只有2~5左右(判断时候的峰值)
      

  14.   

    觉的和sleep没有直接关系,你的代码有问题
    我sleep做的一个WINFORM,几百个线程同时运行都用到sleep也没遇到你说的问题。
    sleep等待线程的时候只占内存CUP占用为0
      

  15.   

    我的也是分析txt文件,cup占用的多少和sleep大小有关系,间隔越小约占CPU
    合理设置sleep的值就能将CPU降低到你想要的程度。
    另外和这个StringBuilder没直接关系,StringBuilder并不能有效提高多少效率楼主好好看看你写的代码吧还是
      

  16.   


    不是不是,sleep后CPU下降,所以说明是可行的降CPU方法,但是现在的问题是,为了数据的实时性,我必须抛弃sleep(3000+循环,每循环sleep(1)的话就要超过3秒,要求的数据刷新间隔在2秒内)所以在没有sleep的情况下CPU一直居高不下,我想问有没有不降低处理速度,而单单降CPU的方式