如何正确使用TThread

时间:2010-10-23 21:50:01

标签: delphi tthread

你能帮帮我吗?我正在编写一个组件(类似于TListView),在我的组件中,我逐个执行3个过程:

procedure findFiles(Path:String); // using FindFirst, FindNext
procedure ArrangeItems; // assigns Item Position
procedure SetIcons;    // Loads Images, resizes, adds to ImageList

我无法理解如何让我的组件使用Threads来执行所有这些过程,至少是第一个(findFiles)。我尝试过不同的方法,但没有任何结果。

这是我所拥有的一个例子(只是一个基本的例子)。

 type
  TSearchThread = class(TThread)
  private
    SIView: TSIView;
  protected
    procedure Execute; override;
    procedure DoSearch;
  public
    constructor Create(fSIView: TSIView);
  end;



 constructor TSearchThread.Create(fSIView: TSIView);
 begin
  SIView := fSIView;
  FreeOnTerminate := True;
  inherited Create(False);
  Priority := tpLower;
 end;

 procedure TSearchThread.Execute;
 begin
  inherited;
  Synchronize(DoSearch);
 end; 

 first I tried to perform 
   SIView.findFiles('C:\');
   ArrangeItems;

然后才执行线程来设置适当的图标(SetIcons):

 procedure TSearchThread.DoSearch;
 begin
  SetIcons;
 end;

它有效但有错误:有时我的组件创建的图标不是所有项目,有时一些项目的图标完全填充黑色,有时我根本没有图标;

然后我决定在线程中执行所有3个程序:

 procedure TSearchThread.DoSearch;
 begin
  SIView.findFiles('C:\');
  ArrangeItems;
  SetIcons;
 end; 

因此,我在创建图标时遇到了同样的错误,而不是在指定的文件夹中搜索它在我的应用程序所在的文件夹中搜索。

为了让你更了解我,我正在尝试用多个标签编写一个文件管理器,所以据我所知,我需要使用Threads,以便在处理多个标签时应用程序不会冻结。

请帮助我理解如何安排我的代码?!!!!   也许你可以举一个例子,因为没有太多关于线程的文档。


你好了。
我已经尝试过AsyncCalls和OmniThreadLibrary。他们都有一个“背景”文件搜索的例子。首先,我发现AsyncCalls更适合我的应用程序,因为它确实很好地完成了它的工作。我使用AsyncCalls来执行我的三个程序,这是我一直在寻找的。 我也尝试使用OmniThreadLibrary调用我的程序,但似乎它们没有在一个线程中执行。 这就是为什么我喜欢AsyncCalls,但我有一个问题,如何在运行时停止IAsyncCall? 我的意思是,例如,正如我之前提到的,我的应用程序是多重攻击的,如果用户打开3个选项卡,并且每个选项卡上执行文件搜索,那么如何在第二个选项卡上停止文件搜索?

为了让你更清楚地了解我想做什么,这里有一个草图:

表单有3个TMemo,3个TButton

var 
 a1, a2, a3: IAsyncCall;


procedure TForm1.Search(Path:String; MEMO:TMemo);
begin
 /////// Finds files and adds to MEMO 
end;

所有三个按钮都是相同的,除了它们指向不同的TMemo(Memo1,Memo2,Memo3);

procedure TForm1.Button1Click(Sender: TObject);

 procedure DoSearch;
 begin
  Search('C:\', Memo1);     
 end;

begin
  a1 := LocalAsyncCall(@DoSearch);

  while AsyncMultiSync([a1], True, 0) = WAIT_TIMEOUT do
      Application.ProcessMessages;
end;

因此,如果我单击所有三个按钮,我将运行3个IAsyncCall。如何在它们仍在运行时停止它们?

2 个答案:

答案 0 :(得分:6)

使用这样的代码

 procedure TSearchThread.Execute;
 begin
  inherited;
  Synchronize(DoSearch);
 end; 

你根本不使用工作线程 - 所有工作都是通过同步调用在主线程中完成的。这是一个不应该使用线程的示例。简而言之,您的执行代码可能如下所示:

 procedure TSearchThread.Execute;
 begin
   if FindFirst(..) then begin
     repeat
       Queue(..); // inform the main thread about the item is found
     until not FindNext(..)
     FindClose;
   end;
   Queue(..); // inform the main thread that the work is completed
              //   and we are about to terminate
 end; 

答案 1 :(得分:5)

我认为你最好的选择是使用AsyncCalls库,它非常易于使用,并且在网页中包含一个与你的例子非常相似的演示。