解决方案 »

  1.   

    AfxBeginThread()创建工作线程。工作线程里可以做一些跟界面无关的事情,比如复杂耗时的计算,音视频的解码等。
      

  2.   


    谢谢,还有一些疑问。
    工作线程做的事情必须和界面无关吗,也就是说,界面上进度条和静态文本框的更新,还是得在主线程里面做?自己设想了一下方案,不知道这样可行吗:
    主线程这边一个个读取文件做处理,如果该文件是MP3文件,那么直接在主线程做标签的写入(这个很快,也就1秒钟左右就完成了),如果该文件不是MP3文件,需要转码,就把他丢给一个工作线程,让工作线程做转码工作,主线程这边把这个文件名称记录下来,然后接着进行下一个文件的读取,当主线程将文件都读取完一遍之后,等待工作线程的转码完成,工作线程的转码完成后,告诉主线程,然后主线程再对刚才记录下的需要转码的一系列文件(现在已经转成MP3了)进行写入标签,最后结束工作,是这样的吗?
      

  3.   

    问问楼主处理完一个mp3后是否释放掉了内存?还有一个windows的进程系统默认分2G的用户内存,100个mp3每个按3M算的话也不过300M,是不会超过的。再者说,如果是内存不够的问题,那程序直接崩溃掉了,也不会出现假死。
    楼主看下,当出现这种情况的时候UI界面还有反应没有?最简单的就是托动窗口看窗口动不动。因为UI线程与你的处理线程不是一个线程,如果这时UI还可以动,说明你的处理逻辑出现了问题,应该是卡在WaitForSingalObject那个位置了。如果窗口也托动不了,那就不是假死,是真死了吧,呵呵!
      

  4.   

    谢谢,还有一些疑问。
    工作线程做的事情必须和界面无关吗,也就是说,界面上进度条和静态文本框的更新,还是得在主线程里面做?自己设想了一下方案,不知道这样可行吗:
    主线程这边一个个读取文件做处理,如果该文件是MP3文件,那么直接在主线程做标签的写入(这个很快,也就1秒钟左右就完成了),如果该文件不是MP3文件,需要转码,就把他丢给一个工作线程,让工作线程做转码工作,主线程这边把这个文件名称记录下来,然后接着进行下一个文件的读取,当主线程将文件都读取完一遍之后,等待工作线程的转码完成,工作线程的转码完成后,告诉主线程,然后主线程再对刚才记录下的需要转码的一系列文件(现在已经转成MP3了)进行写入标签,最后结束工作,是这样的吗?
    1.这么耗时的操作,的确需要使用多线程的,也不难,可以网上找找例子
    2.UI线程的确可以做与UI无关的操作,但是这个操作不能太耗时,或是阻塞,这样会导致UI刷新率低下或是假死
    3.你上述的逻辑是对的,开了线程以后,逻辑差不多就是你描述的那样
    4.转码是个非常消耗CPU的过程,所以CPU占用率很高,你把转码过程放到主线程里就会影响到进度条和文本框的刷新,导致假死,假死的时间应该和你正在转码的文件的体积和比特率有关
    5.WaitForSingleObject一执行,你的界面立马死掉,直到它返回为止,不应该在主线程里调这个函数
    6.如果你使用多线程转码,通过消息来告诉主线程更新界面
      

  5.   


    1、内存是每处理完一个文件以后,都delete释放了的。
    2、我的MP3都是320K高质压缩的,而且打开的文件中还有一些WAV文件,我测试打开的100个左右的音频文件总大小为1.2G。
    3、说了是假死,UI是可以动的,程序没有逻辑问题,即使假死了,我静静等待30-60秒后,程序是成功执行完毕了的,只是中间过程一路假死,鼠标变繁忙状态,进度条不动,但等待30秒左右后,进度条一下满了,程序成功执行完毕。
      

  6.   


    谢谢,还有一些疑问。
    工作线程做的事情必须和界面无关吗,也就是说,界面上进度条和静态文本框的更新,还是得在主线程里面做?自己设想了一下方案,不知道这样可行吗:
    主线程这边一个个读取文件做处理,如果该文件是MP3文件,那么直接在主线程做标签的写入(这个很快,也就1秒钟左右就完成了),如果该文件不是MP3文件,需要转码,就把他丢给一个工作线程,让工作线程做转码工作,主线程这边把这个文件名称记录下来,然后接着进行下一个文件的读取,当主线程将文件都读取完一遍之后,等待工作线程的转码完成,工作线程的转码完成后,告诉主线程,然后主线程再对刚才记录下的需要转码的一系列文件(现在已经转成MP3了)进行写入标签,最后结束工作,是这样的吗?
    1.这么耗时的操作,的确需要使用多线程的,也不难,可以网上找找例子
    2.UI线程的确可以做与UI无关的操作,但是这个操作不能太耗时,或是阻塞,这样会导致UI刷新率低下或是假死
    3.你上述的逻辑是对的,开了线程以后,逻辑差不多就是你描述的那样
    4.转码是个非常消耗CPU的过程,所以CPU占用率很高,你把转码过程放到主线程里就会影响到进度条和文本框的刷新,导致假死,假死的时间应该和你正在转码的文件的体积和比特率有关
    5.WaitForSingleObject一执行,你的界面立马死掉,直到它返回为止,不应该在主线程里调这个函数
    6.如果你使用多线程转码,通过消息来告诉主线程更新界面非常感谢。
    1、根据你说的“2.UI线程的确可以做与UI无关的操作,但是这个操作不能太耗时,或是阻塞,这样会导致UI刷新率低下或是假死”
    也就是说,我对MP3的标签写入工作,其实也可以丢给工作线程来做咯?就是说对文件的写入标签、转码的操作都交给工作线程,主线程就只让它来接收工作线程的汇报,并且在UI上更新进度条等。2、对于“5.WaitForSingleObject一执行,你的界面立马死掉,直到它返回为止,不应该在主线程里调这个函数”
    我用这个函数的原因是:我调用控制台利用lame转码,是一个长时间的工作,程序里如果不用WaitForSingleObjec来暂停主进程,控制台就会在当前语句执行完后被强行关闭掉,而此时我的转码工作肯定没进行完。所以迫不得已才在网上找到了这个方法,不知道如果是多线程的话,使用工作线程是否也会遇到这样的问题呢?
      

  7.   

    1.所有与UI更新无关的操作都最好丢到工作线程里,UI线程只负责更新UI和绘图,你写标签那个操作我觉得应该不太耗时,你可以放在主线程里,当然工作线程最好了
    2.如果你在工作线程里WaitForSingleObject阻塞了的话,只会阻塞你的工作线程,是不会影响到UI的刷新的
    3.还是建议你开多线程转码,UI通过工作线程发消息给主线程来刷新,其实线程没那么复杂,必要时做好线程
    同步就行,对于你的转码,如果你是一个一个的转而不是多个MP3一起转,就不涉及同步的问题,你值开一个线程轮流的转列表里面的MP3就可以了