Hi. Could you help me please. I'm writing a component (something like TListView), In my component I perform 3 procedures one by one:
procedure findFiles(Path:String); // using FindFirst, FindNext
procedure ArrangeItems; // assigns Item Position
procedure SetIcons; // Loads Images, resizes, adds to ImageList
I can not understand how to make my component use Threads to perform all these procedures, at least the first one (findFiles). I've tried different ways but nothing comes out.
Here is a scetch of what I have (just a basic example).
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;
and only then execute the thread to set appropriate icons (SetIcons):
procedure TSearchThread.DoSearch;
begin
SetIcons;
end;
It worked but with bugs: sometimes my component created icons not for all items, sometimes some items had an icon fully filled with black colour and sometimes I had no icons at all;
then I decided to perform all the 3 procedures in the thread:
procedure TSearchThread.DoSearch;
begin
SIView.findFiles('C:\');
ArrangeItems;
SetIcons;
end;
As a result I had the same bugs with creating Icons and instead of searching in a specified folder it searched in the folder where my application was.
For you to understand me more, I am trying to write a file manager with multiple tabs, so as far as I understand, I need to use Threads so that application will not freeze when dealing with multiple tabs.
Could you help me please to understand how to arrange my code?!!!! Maybe you could give an example because there in not many documentation concerning Threading.
Hi again.
I've tried both AsyncCalls and OmniThreadLibrary. They both had an example of "Background" file search. First I found AsyncCalls more suitable for my application as it really did its job well. I used AsyncCalls to perform my three procedures and it was what I had been looking for.
I also tried calling my procedures using OmniThreadLibrary but it seemed like they were not performed in a thread.
That's why I prefered AsyncCalls, but I have a question, HOW TO STOP IAsyncCall when it is running?
I mean, for example, as I've mentioned before my application is multitabbed and if a user opens 3 tabs and on each tab executes file searching, then how can I stop file searching on the second tab?
To make it more clear for you to understand what I want to do, here is a sketch:
A form has 3 TMemo, 3 TButton
var
a1, a2, a3: IAsyncCall;
procedure TForm1.Search(Path:String; MEMO:TMemo);
begin
/////// Finds files and adds to MEMO
end;
All the three buttons do the same, except they point to differen 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;
So, if I click all the three buttons, I'll have 3 IAsyncCall running. How to stop any of them while it is still running?