chrml0606
asked on
Delphi Multitasking (several codes running at same time)
I just wonder about a thing. I'm making a program which must be able to do several things at SAME time. Which means, one thing is the Application.ProcessMessage s. For the application to not hang when doing some operations (like sending email). Lets say if I want to copy a 4 files on 200 megabyte in the app, and want the application to behave normally (like Outlook, Winzip, etc... when they do something which takes time) while copying. That means that I have to do these loops at SAME time:
//***For updating app:***
Repeat
Application.ProcessMessage s;
Until cancelupdate;
//***And this for the copying itself for example ***
For file := 0 to 4 do
begin
filename :='C:\file'+inttostr(file) +'.zip';
newfilename := 'C:\file'+inttostr(file)+' _new.zip';
If FileExists(filename) Then
begin
CopyFile(filename,newfilen ame,false) ;
end;
end;
Since the last one will take about 20 seconds, then the application can't seems like it has crashed in the meantime, and if I run ProcessMessages every loop, then it only will react every 5th second, so therefore the other loop that does the ProcessMessages be done at the same time as the loop. How can that be done? I've tried with timers (but they need ProcessMessages to respond), and I've tried with a seperate loop (but then it's stuck in the loop, and won't go to the filecopying). How would I get this work then?
//***For updating app:***
Repeat
Application.ProcessMessage
Until cancelupdate;
//***And this for the copying itself for example ***
For file := 0 to 4 do
begin
filename :='C:\file'+inttostr(file)
newfilename := 'C:\file'+inttostr(file)+'
If FileExists(filename) Then
begin
CopyFile(filename,newfilen
end;
end;
Since the last one will take about 20 seconds, then the application can't seems like it has crashed in the meantime, and if I run ProcessMessages every loop, then it only will react every 5th second, so therefore the other loop that does the ProcessMessages be done at the same time as the loop. How can that be done? I've tried with timers (but they need ProcessMessages to respond), and I've tried with a seperate loop (but then it's stuck in the loop, and won't go to the filecopying). How would I get this work then?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ah, ok, I see, but where is the procedure that the thread is doing? I mean, if I was going to do some filecopying here, then where would I have the filecopying code?
The ThrdDemo sample makes it a little more obvious:
procedure TThreadSortForm.BubbleSort BoxPaint(S ender: TObject);
begin
PaintArray(BubbleSortBox, BubbleSortArray);
end;
procedure TThreadSortForm.SelectionS ortBoxPain t(Sender: TObject);
begin
PaintArray(SelectionSortBo x, SelectionSortArray);
end;
procedure TThreadSortForm.QuickSortB oxPaint(Se nder: TObject);
begin
PaintArray(QuickSortBox, QuickSortArray);
end;
procedure TThreadSortForm.FormCreate (Sender: TObject);
begin
RandomizeArrays;
end;
procedure TThreadSortForm.StartBtnCl ick(Sender : TObject);
begin
RandomizeArrays;
ThreadsRunning := 3;
with TBubbleSort.Create(BubbleS ortBox, BubbleSortArray) do
OnTerminate := ThreadDone;
with TSelectionSort.Create(Sele ctionSortB ox, SelectionSortArray) do
OnTerminate := ThreadDone;
with TQuickSort.Create(QuickSor tBox, QuickSortArray) do
OnTerminate := ThreadDone;
StartBtn.Enabled := False;
end;
procedure TThreadSortForm.BubbleSort
begin
PaintArray(BubbleSortBox, BubbleSortArray);
end;
procedure TThreadSortForm.SelectionS
begin
PaintArray(SelectionSortBo
end;
procedure TThreadSortForm.QuickSortB
begin
PaintArray(QuickSortBox, QuickSortArray);
end;
procedure TThreadSortForm.FormCreate
begin
RandomizeArrays;
end;
procedure TThreadSortForm.StartBtnCl
begin
RandomizeArrays;
ThreadsRunning := 3;
with TBubbleSort.Create(BubbleS
OnTerminate := ThreadDone;
with TSelectionSort.Create(Sele
OnTerminate := ThreadDone;
with TQuickSort.Create(QuickSor
OnTerminate := ThreadDone;
StartBtn.Enabled := False;
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for help :)! Accepted your answer, and gave the other dude 40 points for showing interest :)!
chrml0606 :
you will have to override the Execute Method and place your code in there.
Sahil
you will have to override the Execute Method and place your code in there.
Sahil
ASKER
Yup, I know :D! I got it working thanks to sftweng.
Objects
The example demonstrates using the TProgressBar and TThread objects.
Running
To run this example, load the project file from the Help\Examples\PrgrsBar directory.
Description
This example illustrates the use of a progress bar control, how to update the control, and how to manage threads during such a process.
unit Pg1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls, Pg2;
const
WM_ThreadDoneMsg = WM_User + 8;
type
TForm1 = class(TForm)
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Button1: TButton;
Button2: TButton;
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
Bevel1: TBevel;
Bevel2: TBevel;
Label1: TLabel;
Label2: TLabel;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
MyThread1 : TMyThread; // thread number 1
MyThread2 : TMyThread; // thread number 2
Thread1Active : boolean; // used to test if thread 1 is active
Thread2Active : boolean; // used to test if thread 2 is active
procedure ThreadDone(var AMessage : TMessage); message WM_ThreadDoneMsg; // Message to be sent back from thread when its done
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender
{ The thread will destroy iteself when it is done executing because FreeOnTerminate is set to true.
The first paramter is the priority, and the second is the progressbar to update.
}
begin
if (MyThread1 = nil) or (Thread1Active = false) then // make sure its not already running
begin
MyThread1 := TMyThread.CreateIt(TrackBa
Thread1Active := true;
end
else
ShowMessage('Thread still executing');
end;
procedure TForm1.Button2Click(Sender
begin
if (MyThread2 = nil) or (Thread2Active = false) then // make sure its not already running
begin
MyThread2 := TMyThread.CreateIt(TrackBa
Thread2Active := true;
end
else
ShowMessage('Thread still executing');
end;
procedure TForm1.Button3Click(Sender
begin
if (MyThread1 <> nil) and (Thread1Active = true) then // check to see if it is running
MyThread1.Terminate
else
ShowMessage('Thread not started');
end;
procedure TForm1.Button4Click(Sender
begin
if (MyThread2 <> nil) and (Thread2Active = true) then // check to see if it is running
MyThread2.Terminate
else
ShowMessage('Thread not started');
end;
procedure TForm1.ThreadDone(var AMessage: TMessage); // keep track of when and which thread is done executing
begin
if ((MyThread1 <> nil) and (MyThread1.ThreadID = cardinal(AMessage.WParam))
begin
Thread1Active := false;
end;
if ((MyThread2 <> nil) and (MyThread2.ThreadID = cardinal(AMessage.WParam))
begin
Thread2Active := false;
end;
end;
procedure TForm1.FormCreate(Sender: TObject); // initialize to zero
begin
Thread1Active := false;
Thread2Active := false;
end;
procedure TForm1.TrackBar1Change(Sen
begin
if (MyThread1 <> nil) and (Thread1Active = true) then
MyThread1.priority := TThreadPriority(TrackBar1.
end;
procedure TForm1.TrackBar2Change(Sen
begin
if (MyThread2 <> nil) and (Thread2Active = true) then
MyThread2.priority := TThreadPriority(TrackBar2.
end;
procedure TForm1.FormDestroy(Sender:
begin
if (MyThread1 <> nil) and (Thread1Active = true) then
begin
MyThread1.Terminate;
MyThread1.WaitFor; // wait for it to terminate
end;
if (MyThread2 <> nil) and (Thread2Active = true) then
begin
MyThread2.Terminate;
MyThread2.WaitFor;
end;
end;
end.