我在主窗体中创建了两个线程分别控制两个进度条pb1和pb2。
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;type
  TForm1 = class(TForm)
    pb1: TProgressBar;
    pb2: TProgressBar;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
  public
    ThreadsRunning:Integer;
    procedure ThreadDone(Sender: TObject);
  end;var
  Form1: TForm1;implementation
uses
  UnitThread;
{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
  t1,t2:TTest;
begin
  btn1.Enabled:=False;
  ThreadsRunning:=2;
  t1:=TTest.Create(pb1);
  t2:=TTest.Create(pb2);
  t1.OnTerminate:=ThreadDone;
  t2.OnTerminate:=ThreadDone;
end;procedure TForm1.ThreadDone(Sender: TObject);
begin
  Dec(ThreadsRunning);
  if ThreadsRunning = 0 then
  begin
    btn1.Enabled := True;
  end;
end;
end.
线程类代码如下:
unit UnitThread;interface
uses
  Classes, ComCtrls;
type
  TTest=class(TThread)
  private
    Fpb:TProgressBar;
    procedure process;
  protected
    procedure Execute; override;
  public
    constructor Create(pb:TProgressBar);
  end;
implementationconstructor TTest.create(pb:TProgressBar);
begin
  inherited Create(False);
  fpb:=pb;
  FreeOnTerminate := True;
end;procedure TTest.Execute;
begin
  Synchronize(process);
end;procedure TTest.process;
var
  i:Integer;
begin
  Fpb.Max:=10000;
  i:=0;
  while i<10000*2 do
    begin
      Inc(i);
      Fpb.Position:=(Fpb.Position+1) mod Fpb.Max;
    end;
end;end.
没弄过多线程的东西,望过来人帮我这个门外人跨过这个门槛!感激不尽!

解决方案 »

  1.   

    procedure TTest.Execute;
    begin
     process;
    end;
    -------------------------------------------------------
    本回复由大傻的破玩意儿【CSDN's forum Explorer】完成!
    软件功能强大,速度超快!!支持中...
    软件下载地址:http://CoolSlob.ys168.com
      

  2.   

    我也试到这个方法了。可是原因是什么呢?为什么用Synchronize就不行呢?不是说操作Vcl的要用Synchronize吗(网上看到的)?再就是线程在运行的时候,主窗体并不能及时的响应用户的操作(比如托动窗体),这又是什么原因呢?
      

  3.   

    是不是应该给程序自己决定消息处理的机制啊,比如 Application.ProcessMessages,释放系统控制权,由程序自己处理消息!
      

  4.   

    HEHE  ~~因为你的机器就一个CPU啊!!
      

  5.   

    再就是线程在运行的时候,主窗体并不能及时的响应用户的操作(比如托动窗体)
    ----------------
    procedure TTest.process;
    var
      i:Integer;
    begin
      Fpb.Max:=10000;
      i:=0;
      while i<10000*2 do
        begin
          Inc(i);
          Fpb.Position:=(Fpb.Position+1) mod Fpb.Max;
          Sleep(1);//加了这行
        end;
    end;
    -------------------------------------------------------
    本回复由大傻的破玩意儿【CSDN's forum Explorer】完成!
    软件功能强大,速度超快!!支持中...
    软件下载地址:http://CoolSlob.ys168.com
      

  6.   

    偶不会说,只会做,你自己去慢慢领会吧-------------------------------------------------------
    本回复由大傻的破玩意儿【CSDN's forum Explorer】完成!
    软件功能强大,速度超快!!支持中...
    软件下载地址:http://CoolSlob.ys168.com
      

  7.   

    procedure TTest.Execute;
    begin
    Synchronize(process);
    sleep(0); //让出线程运行权
    end;
      

  8.   

    Synchronize ?? 这样一来,相当于在主线程中执行。
      

  9.   

    你的执行函数
    仅这句Fpb.Position:=(Fpb.Position+1) mod Fpb.Max; 用Synchronize包装起来就是了
      

  10.   

    To:terence4444(T4)
    用你说的方法,没有解决问题。窗体还是无法响应。并且两个进度条也不是同时“前进”。
      

  11.   

    To:饭桶超人
    在你说的那个地方加了sleep后,窗体能及时响应用户操作了。即使是sleep(0)也行。
    不过,可以看出进度条的速度明显慢了很多。
      

  12.   

    Delphi里的Demo里的那个线程的例子并没有用sleep,可是那个程序也是可以及时响应用户操作的。这是为什么?
    还有就是用了Synchronize两个线程就不是并列运行,这不就失去了多线程的意义了吗?原因何在?
    各位高手!
      

  13.   

    不管你多少个线程,只要你的电脑是一个cpu的就是排队运行的,如果是多个cpu则操作系统会分配空闲的cpu给程序的其中一个线程,所以不多解释了多线程的用处在于子线程的任何操作不会影响主线程的响应操作