首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用TThread

如何正确使用TThread
EN

Stack Overflow用户
提问于 2010-10-23 21:50:01
回答 2查看 3K关注 0票数 0

你能帮帮我吗。我正在编写一个组件(类似于TListView),在组件中我一个一个地执行三个过程:

代码语言:javascript
复制
procedure findFiles(Path:String); // using FindFirst, FindNext
procedure ArrangeItems; // assigns Item Position
procedure SetIcons;    // Loads Images, resizes, adds to ImageList

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

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

代码语言:javascript
复制
 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):

代码语言:javascript
复制
 procedure TSearchThread.DoSearch;
 begin
  SetIcons;
 end;

它起作用了,但有缺陷:有时我的组件创建的图标不是为所有的项目,有时有些项目有一个充满黑色的图标,有时我根本没有图标;

然后,我决定执行线程中的所有三个过程:

代码语言:javascript
复制
 procedure TSearchThread.DoSearch;
 begin
  SIView.findFiles('C:\');
  ArrangeItems;
  SetIcons;
 end; 

因此,我在创建图标时有相同的bug,而不是在指定的文件夹中搜索,而是在我的应用程序所在的文件夹中搜索。

为了让您更好地理解我,我正在尝试编写一个带有多个选项卡的文件管理器,因此据我了解,我需要使用Thread,以便应用程序在处理多个选项卡时不会冻结。

你能帮我理解一下怎么安排我的代码吗?也许您可以举个例子,因为没有太多关于线程的文档。

再来一次嗨。

我试过AsyncCalls和OmniThreadLibrary。他们都有“背景”文件搜索的例子。首先,我发现AsyncCalls更适合我的应用程序,因为它确实做得很好。我用AsyncCalls来执行我的三个程序,这就是我一直在寻找的。我还试着使用OmniThreadLibrary调用我的过程,但它们似乎不是在线程中执行的。这就是我更喜欢AsyncCalls的原因,但我有一个问题:如何在IAsyncCall运行时停止它?例如,正如我之前提到的,我的应用程序是多选项卡,如果用户打开3个选项卡,每个选项卡上执行文件搜索,那么如何停止对第二个选项卡的文件搜索?

为了让你更清楚地理解我想做什么,下面是一个草图:

一个表单有3 TMemo,3 TButton

代码语言:javascript
复制
var 
 a1, a2, a3: IAsyncCall;


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

除了指向不同的TMemo (Memo1,Memo2,Memo3)外,这三个按钮都是相同的;

代码语言:javascript
复制
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。如何在它还在运行的时候阻止其中的任何一个?

EN

回答 2

Stack Overflow用户

发布于 2010-10-24 01:19:13

用这样的代码

代码语言:javascript
复制
 procedure TSearchThread.Execute;
 begin
  inherited;
  Synchronize(DoSearch);
 end; 

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

代码语言:javascript
复制
 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; 
票数 7
EN

Stack Overflow用户

发布于 2010-10-23 23:45:51

我认为您最好的选择是使用AsyncCalls库,wich非常容易使用,并且在网页中包含了一个非常类似于您的示例的演示。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4006253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档