首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

[]-为什么这个简单多线程代码,执行后CPU好高,而且根本没有多线程的效果

2012-12-30 
[求助]--------为什么这个简单多线程代码,执行后CPU好高,而且根本没有多线程的效果?本帖最后由 cowboamo

[求助]--------为什么这个简单多线程代码,执行后CPU好高,而且根本没有多线程的效果?
本帖最后由 cowboamo 于 2012-12-06 22:04:59 编辑
高人帮看看,小弟刚学多线程,程序,就是要让线程和ProgressBar1里的进度同步,
问题如下:
1.但为什么一运行程序,系统都动不了了,要等运行完了才能动?
2.为什么?有时候出现程序执行完了,但进度条确在70%左右完了,或者是程序没完,进度条完了?


如何改,请问

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

  {声明多线程}
  type 
  TMyThread2 = class(TThread)
  private   
           ps1:TProgressBar;
  public 
    procedure    calt;   
    constructor Create(parent:TProgressBar); 
    procedure   Execute;override;   
  end; 
  
type
  TForm2 = class(TForm)
    ProgressBar1: TProgressBar;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
    L=10000;
var
  Form2: TForm2;

implementation

{$R *.dfm}
constructor    TMyThread2.Create(parent:TProgressBar);   
begin   
   ps1    :=    parent;   
   inherited    Create(false);   
end;   
   

procedure  TMyThread2.calt; 
var
  i:Integer;
begin

  //FreeOnTerminate := True; {这可以让线程执行完毕后随即释放}          
  ps1.Max := L;
  for i := 1 to L do
  begin
    ps1.StepBy(1);
  end;
  
end;

procedure TMyThread2.Execute;
begin
    synchronize(calt);   
    if    Terminated    then    Exit;   
end;


procedure TForm2.FormCreate(Sender: TObject);
begin
    TMyThread2.Create(ProgressBar1);  //调用
end;

end.

[解决办法]
需要延时吧。。10000格一下就跑完了
[解决办法]
{ TMyThread2 }

procedure TMyThread2.calt;
begin
  ps1.StepBy(1);
end;

constructor TMyThread2.Create(parent: TProgressBar);
begin
  ps1 := parent;
  inherited Create(False);
end;

procedure TMyThread2.Execute;
begin
  ps1.Max := L;
  for i := 1 to ps1.Max do
  begin
    if Terminated then
      Break;
    synchronize(calt);
  end;
end;

------解决方案--------------------


这个线程执行过程中的确是高cpu,你可以创建多个thread,每个的占用率就会降下来
单个的话,可以加sleep
[解决办法]
你在线程的 Execute 里使用 synchronize(calt) ,还是相当于在主线程中执行,完全没有起到线程的做用。

先定义一个消息
WM_MyMessage=WM_USER+2000;
定义一个进度的变量
  app_Position:Integer;
窗体接收这个消息
public
  procedure OnWM_MyMessage(var mes:tmessage);message WM_MyMessage;
begin
  ProgressBar1:=app_Position;
end;

//将窗体的 Handle 在创建线程里给传入,线程里执行
procedure TMyThread2.Execute;
begin
    while true do
    begin
       //执行要完成的工作,
       inc(app_Position);
       postmessage(formHandle,WM_MyMessage,0,0);
       sleep(100); //如果感觉太快或太慢,可以调整
    end; 
end;


也可以不用消息,窗体上放一个定时器,每一秒去刷新一下进度条的值
其实用定时器的方式最简单,也不至于一下就到头了。

[解决办法]
将占用时长的代码写在线程里。
synchronize是将过程加载到主线程执行。
你这里的calt过程这样写,明显将耗时的循环在主线程执行了,肯定会使界面卡死,CPU占用高的。

热点排行