to tianlei123:
怎么用?能详细点儿吗?
谢谢!

解决方案 »

  1.   

    给分不多,要求不低!!!waitforsingleobject(要执行的线程的句柄,等待时间或infinite(一直等到线程执行完毕));将该句放在 ***.resume之后
      

  2.   

    to tianlei123:
    不要这样,帮帮忙嘛,我的分不多,要不然我肯定多给你加几十分,下次有分了再给你补上,
    行了吧?谢谢你罗!
    可是问题还没解决:我的线程***.resume执行后,并没后terminate,而只是挂起了suspend;
    那我该怎么办?
      

  3.   

    线程执行到end时已经终止。只是没有free
    在***.resume之前再加一句:***.FreeOnTerminate:=true;
      

  4.   

    用了freeonterminate 后用resume好像不能唤醒吧。因为我一定要用resume随时唤醒它。
      

  5.   

    你到底要干什么?主进程:
    ....
    ***.resume;//唤醒线程执行
    waitforsingleobject(...,infinite);//等...直到***执行完毕,如果你的线程是死循环,这句永远过不了。
    ....//  <-- 这一句除非***执行完才会执行
      

  6.   

    在主进程中等待会导致程序在等待期间不响应用户输入。可以在线程中直接修改主线程中的变量。
    如果存在多个线程同时访问同一变量的问题,可以用TCritialSection进行同步。
      

  7.   

    to lyre:
    Tcriticalsection 如何用,我在联机帮助里没查到,查书也没找到。
    另外还问你一个问题:
        如何在delphi里面手工触发事件,比如:我要在onclick事件结束立即执行ondoubleclick时间,那在onclick的结尾应该用:ondoubleclick(  ),我不知道括号里面的参数如何设?你能举一个事件中参数较多的触发例子给我看一下吗?
    谢谢!
      

  8.   

    to lyre:
    能不能给一个Tcriticalsection的例子?谢谢!
      

  9.   

    to lyre:
      你怎么不理我呀?
      

  10.   

    你想取回经线程处理过的变量回来应该有很多办法的
    我来献上一条最笨的方法:
    先定义共有变量: 
    type Tvardata=recorder
    data : 自定义;
    new  : boolean;
    end;
    当有数据要线程处理是置new为false;
    在线程中处理后在置new为true;
    不只能不能给点分!方法是土了些
    但在作线程时这可是一种很有效的方法.
      

  11.   

    to jasminemao(jasmine):
      抱歉前段时间没有上网,让你久候了。先给你一个用TCriticalSection的例子://------------------------------------------------------------------
    //Form的定义
    object Form1: TForm1
      Left = 254
      Top = 213
      Width = 207
      Height = 175
      ActiveControl = Button1
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object SpinEdit1: TSpinEdit
        Left = 24
        Top = 24
        Width = 121
        Height = 22
        MaxValue = 0
        MinValue = 0
        TabOrder = 0
        Value = 9
      end
      object SpinEdit2: TSpinEdit
        Left = 24
        Top = 56
        Width = 121
        Height = 22
        MaxValue = 0
        MinValue = 0
        TabOrder = 1
        Value = 9
      end
      object Button1: TButton
        Left = 24
        Top = 96
        Width = 75
        Height = 25
        Caption = 'Start!'
        TabOrder = 2
        OnClick = Button1Click
      end
    end//Form对应的单元
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Sample,
      StdCtrls, Spin;type
      TForm1 = class(TForm)
        SpinEdit1: TSpinEdit;
        SpinEdit2: TSpinEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    var
      Thread1, Thread2: TMyThread;
    begin
      Thread1 := TMyThread.Create(False);
      Thread2 := TMyThread.Create(False);  SpinEdit1.Value := Thread1.WaitFor;
      SpinEdit2.Value := Thread2.WaitFor;  Beep;
      Thread1.Free;
      Thread2.Free;
    end;end.//Sample单元
    unit Sample;interface
    uses
      Classes, SyncObjs, Windows;type
      TMyThread = class(TThread)
        procedure Execute; override;
      end;implementation
    var
      Count: Integer;
      CS: TCriticalSection;procedure TMyThread.Execute;
    begin
      CS.Enter;  //进入临界段。可以设想成一个门槛,只允许一个线程进入
      try        //这里本不必用try..finally..end句式,但这样做是一个好的习惯
        while Count > 0 do
        begin
          Sleep(1000);  //适当延时,增加不同进程冲突的机会
          Count := Count -1;
        end;
      finally
        CS.Leave;  //离开临界段
      end;  ReturnValue := Count;  //作为WaitFor的返回值
    end;initialization
      Count := 1;
      CS := TCriticalSection.Create;
    finalization
      CS.Free;
    end.//-------------------------------------------------------
    你可以再把CS.Enter和CS.Leave封掉再看看效果。关于楼上提供的方法:
        似乎主线程中要用轮询的方法来查询该值,效率不是很高。而且假如有多个线程同时修改,则不可避免地会导致共享冲突问题。关于你的第二个问题:
        一般情况下不需要自己触发事件,可以将组件的该事件重复一下,或调用相应的方法。例如
    TButton的OnClick可以用TButton.Click触发,一些组件的OnSelect事件则可以将其Selected属性重新赋值。如果坚持要自己触发事件,就要到帮助中查清楚各参数的含义。作为一个惯例,参数中的Sender指的是发生事件的控件。比方说,一个Button1:TButton的OnClick事件要亲自触发,你就得这样写:
      if Assigned(Button1.OnClick) then
        Button1.OnClick(Button1);
    当然,如果按你的要求,在OnClick事件处理程序中再触发OnDoubleClick事件,就可以直接使用Sender:
      if Assigned(OnDoubleClick) then
        OnDoubleClick(Sender);说了这么多,不知你满不满意。不满意可以再问,满意的话就给我加点分:-)
      

  12.   

    HTML测试,不好看不要怪我:-)<tr><td><PRE><TT><PRE><TT><PRE><TT><PRE><TT><PRE><TT>
    <FONT COLOR="#000000"><PRE><TT><PRE><TT><font color="#000000"><b>unit</b></font> Sample<font color="#000000">;</font><font color="#000000"><b>interface</b></font>
    <font color="#000000"><b>uses</b></font>
      Classes<font color="#000000">,</font> SyncObjs<font color="#000000">,</font> Windows<font color="#000000">;</font><font color="#000000"><b>type</b></font>
      TMyThread <font color="#000000">=</font> <font color="#000000"><b>class</b></font><font color="#000000">(</font>TThread<font color="#000000">)</font>
        procedure Execute<font color="#000000">;</font> override<font color="#000000">;</font>
      <font color="#000000"><b>end</b></font><font color="#000000">;</font><font color="#000000"><b>implementation</b></font>
    <font color="#000000"><b>var</b></font>
      Count<font color="#000000">:</font> <font color="#000000"><b>Integer</b></font><font color="#000000">;</font>
      CS<font color="#000000">:</font> TCriticalSection<font color="#000000">;</font>procedure TMyThread<font color="#000000">.</font>Execute<font color="#000000">;</font>
    <font color="#000000"><b>begin</b></font>
      <font color="#7f7f7f"><i>//CS.Enter;</i></font>
      try
        <font color="#000000"><b>while</b></font> Count <font color="#000000">&#62;</font> <font color="#0000ff">0</font> do
        <font color="#000000"><b>begin</b></font>
          Sleep<font color="#000000">(</font><font color="#0000ff">1000</font><font color="#000000">)</font><font color="#000000">;</font>
          Count <font color="#000000">:</font><font color="#000000">=</font> Count <font color="#000000">-</font><font color="#0000ff">1</font><font color="#000000">;</font>
        <font color="#000000"><b>end</b></font><font color="#000000">;</font>
      finally
        <font color="#7f7f7f"><i>//CS.Leave;</i></font>
      <font color="#000000"><b>end</b></font><font color="#000000">;</font>
      ReturnValue <font color="#000000">:</font><font color="#000000">=</font> Count<font color="#000000">;</font>
    <font color="#000000"><b>end</b></font><font color="#000000">;</font>initialization
      Count <font color="#000000">:</font><font color="#000000">=</font> <font color="#0000ff">1</font><font color="#000000">;</font>
      CS <font color="#000000">:</font><font color="#000000">=</font> TCriticalSection<font color="#000000">.</font>Create<font color="#000000">;</font>
    finalization
      CS<font color="#000000">.</font>Free<font color="#000000">;</font>
    <font color="#000000"><b>end</b></font><font color="#000000">.</font>
    </TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></FONT></TT></PRE></FONT>
    </tr></td>
      

  13.   

    你可以用TEVENT呀
    主线程创建了子线程之后就可以WAITFOR了,子线程处理完后SetEvent就可以了。试试看
    eg:
    主线程:
    Wait:TEvent;
    begin
     Wait:=TEvnet.Create(nil,false,false,'');
     //创建子线程
      Tss.create(Wait);
      Wait.WaitFor(5000);
    子线程:
     TS1=class (TThread)
    private
      evWait:TEvent;
    ...
    public
      constructor create(pWait:TEvent);
    ...
    constructor TS1.create(pWait:TEvent)
    begin
      evWait:=pWait;
      FreeOnTerminate:=true;
      inherited Create(false);
    end;
    ...
    TS1.Execute:
    ....
       处理完之后
       evWait.SetEvent;
    ....