线程中临界区对象(TCriticalSection)不起作用

求助:线程中临界区对象(TCriticalSection)不起作用。
写了个数据处理线程,处理结果输出到一个TMemo对象,为避免显示混乱,设立了一个临界区,控制输出过程,开始输出到输出结束之间的代码由临界区负责保护,但是我发现,临界区完全没有作用,怎么回事?


线程代码:


  Tb = class(TThread)
  private
    CS: TCriticalSection;                                         //临界区对象
    mm: TMemo;                                                    //用于显示的memo
    fshowvalue: string;                                           //用于显示的数据
    procedure showmm();                                           //显示数据过程
    procedure setshowvalue(const Value: string);                  //设置显示数据的过程
  protected
    procedure Execute; override;
  public
    constructor Create(mmo: TMemo);                               //创建时传入显示控件
    destructor Destroy; override;
    procedure Next();                                             //显示下一个输入的数据
    property showvalue: string read fshowvalue write setshowvalue;//设置显示的数据
  end;

implementation

{ Tb }

constructor Tb.Create(mmo: TMemo);
begin
  inherited Create(True);
  mm := mmo;
  CS := TCriticalSection.Create;
  fshowvalue := '';
  Resume;
end;

destructor Tb.Destroy;
begin
  CS.Leave;
  CS.Free ;
  inherited;
end;

procedure Tb.Execute;
begin
  inherited;
  while True do
  begin
    Synchronize(showmm);

    Application.ProcessMessages ;
  end;

end;

procedure Tb.showmm;
begin
  if fshowvalue <> '' then          //不输出空串
    mm.Lines.Add(fshowvalue);
end;

procedure Tb.Next;
begin
  CS.Leave ;                        //离开临界区
end;

procedure Tb.setshowvalue(const Value: string);
begin
  CS.Enter;                         //进入临界区,应该只要没有离开临界区,这段
                                    //代码就不应该被重复执行,而是等待上次调用
                                    //离开临界区

                                    //但实际上,只要进入这个过程就会往下执行,
                                    //临界区对象似乎完全没有作用,为什么???
  mm.Lines.Clear;
  fshowvalue := Value;
end;



调用代码:


procedure TForm1.FormCreate(Sender: TObject);
begin
  bb := Tb.Create(Mmo1);    //创建线程
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  bb.showvalue := Edit1.Text ;    //设置要显示的数据
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  bb.Next ;    //显示下一个数据
end;



求助一下,为什么只要按下Button5,Mmo1上就会输出新设置进去的数据?

我原先设想是:第一次按下Button5,Mmo1上显示数据,修改edit1的数据,再次点下Button5,新数据不会被输出到Mmo1上,点Button6后,才会在Mmo1上输出新设的数据。

我的环境是WinXP sp3,delphi6,谢谢。
------解决思路----------------------
我原先设想是:第一次按下Button5,Mmo1上显示数据,修改edit1的数据,再次点下Button5,新数据不会被输出到Mmo1上,点Button6后,才会在Mmo1上输出新设的数据。


这种应用,用信号明显要合适点,用TCriticalSection,要麻烦些

procedure Tb.Execute;
begin
  inherited;
  while True do
  begin
    Synchronize(showmm);
    Application.ProcessMessages ;
  end;
end;
这是让某一个CPU一直运行的节奏,不好,
------解决思路----------------------
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    procedure DoShowData;
  public
  end;

var
  Form1: TForm1;

  CS: TCriticalSection;
  dwDest : LongWord;
  dwThreadCount : integer;

implementation

{$R *.dfm}

type
  TAddThread = class(TThread)
  private
  protected
    procedure Execute; override;
  end;

procedure TAddThread.Execute;
var
  i : integer;
begin
  FreeOnTerminate := True;
  CS.Enter;
  Inc(dwThreadCount); //线程计数,多少个线程进入
  CS.Leave;

  for i := 1 to 30000000 do begin
    CS.Enter;  //如果注释掉这句和Leave那句,看结果
    dwDest := dwDest + 1;
    CS.Leave;  //如果注释掉这句和Leave那句,看结果
  end;

  CS.Enter;
  Dec(dwThreadCount);
  if dwThreadCount=0 then //最后一个结束的线程显示数据
    Synchronize(Form1.DoShowData);
  CS.Leave;
end;

procedure TForm1.DoShowData;
begin
  Memo1.Lines.Add(IntToStr(dwDest));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  dwDest := 0;
  CS := TCriticalSection.Create;
  TAddThread.Create;
  TAddThread.Create;
end;


这个代码给你掩饰临界区的作用,如果注释掉for循环中的临界区那2句,看结果是否=60000000,同时可以看到怎么显示同步到主线程操作界面控件
------解决思路----------------------
线程实际执行的代码只是EXCUTE部分,其它不被excute调用的代码,都是主线程执行的。所以几个线程锁和解锁的对象,只能在excute才有意义
------解决思路----------------------
建议你把进程中跟界面相关的放在一个线程中处理。除非你有非常复杂的UI渲染。其他线程不要处理窗口消息相关的东西,做完辅助工作要通知界面时,用发windows消息的方式告诉主线程。
用Synchronize()方法同步给主线程做事一个很别扭的不正常的方式。不知道borland当初为啥会想出一个这样的方法来。可能是为了满足小白的需求吧。
------解决思路----------------------
线程与主线程之间几乎是隔绝的,线程中是不能对主线程进行操作。必须通过消息才能处理。
------解决思路----------------------
这写法,我是真没有弄懂。临界的概念与用途,还没有明白,先学学,生产者与消者费的模式