?
Solved

Working with a simple thread

Posted on 2006-04-04
4
Medium Priority
?
343 Views
Last Modified: 2010-04-04
Hello Guys, I need to create a simple thread where I can insert this code below in my unit, but Thread is something new for me and I need you help. Let me explain what I need.

I have a button that calls a storeprocedure, it takes approximately between 5 and 10 minutes, it depends on the month, the user needs to know that the process is on and needs to wait until it finishes. For this I want to create a progress bar  in my form that is the same where I call the storeprocedure through ADOStoredProc. While it is working I want to start a loop where a progressbar is shown, like this code:

procedure startLoop;
Const
  V = 100;
Var
  I : Integer;

begin
  Para := False;
  ProgressBar1.Max := V;
  I := 0;
  while Not Stop do
  Begin
    If I < V Then For I := 0 to V     do
       Begin
         Application.ProcessMessages;
         ProgressBar1.Position := I;
         Sleep(01);
       End;

    If I > V Then For I := V downto 0 do
       Begin
         Application.ProcessMessages;
         ProgressBar1.Position := I;
         sleep(01)
       End;
  End
end;

You can note here that there is a variable named Stop, it is a boolean variable and when my storeprocedure finishes I will set it to true.

Alex
0
Comment
Question by:hidrau
  • 2
4 Comments
 
LVL 14

Accepted Solution

by:
Pierre Cornelius earned 2000 total points
ID: 16375526
*.pas
====
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms,
  ComCtrls, StdCtrls, Grids, DBGrids, DBTables, DB;

type
  TProgressThread = class(TThread)
  public
    procedure Execute; override;
  end;

  TForm1 = class(TForm)
    Table1: TTable;
    Button1: TButton;
    ProgressBar1: TProgressBar;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var ProgThread: TProgressThread;
begin
  ProgThread:= TProgressThread.Create(false);
  try
    ProgThread.FreeOnTerminate:= true;
    //execute your stored procedure here
    Table1.Open; //just for demo
    ProgThread.Terminate;
  except
    ProgThread.Terminate;
    raise;
  end;
end;

{ TProgressThread }

procedure TProgressThread.Execute;
var pb: TProgressbar;
begin
  pb:= Form1.ProgressBar1;
  pb.DoubleBuffered:= true;
  pb.Max:= 100; //increase to slow down
  pb.Min:= 0;
  pb.Position := 0;
  while (Not Terminated) do
  begin
    if (pb.Position = pb.Max) then pb.Step:= -1;
    if (pb.Position = pb.Min) then pb.Step:= 1;
    pb.StepIt;
    pb.Update;
  end;
end;

end.



*.dfm
====
object Form1: TForm1
  Left = 192
  Top = 114
  Width = 696
  Height = 480
  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 Button1: TButton
    Left = 8
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Open'
    TabOrder = 0
    OnClick = Button1Click
  end
  object ProgressBar1: TProgressBar
    Left = 104
    Top = 8
    Width = 569
    Height = 17
    Smooth = True
    TabOrder = 1
  end
  object DBGrid1: TDBGrid
    Left = 24
    Top = 56
    Width = 633
    Height = 297
    DataSource = DataSource1
    TabOrder = 2
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
  end
  object Table1: TTable
    DatabaseName = 'DBDEMOS'
    SessionName = 'Default'
    ReadOnly = True
    TableName = 'items.db'
    Left = 160
    Top = 8
  end
  object DataSource1: TDataSource
    DataSet = Table1
    Left = 208
    Top = 8
  end
end

Regards
Pierre
0
 
LVL 2

Expert Comment

by:Mainiacfreakus
ID: 16375555
Pierre C...

Nice solution... but all the stuff in your execute method should rather look like this:

  Synchronize(Setup);
  While not(Terminated) or not(Stop) do Begin
    Synchronize(UpdateProgress);
  End;

You are working with VCL components and if you don't use Synchronize, your application can get EAccessViolation exceptions.

Mainiacfreakus
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 16375738

I don't think Synchronize is necessary here as the main thread does not access any of the VCL objects while the progress thread is running. The only call between the progress thread start and end is the execution of a stored procedure which is at database level i.e. nothing else can happen in the app while the thread is running until such time as an error occurs or the SP is done both instances which are taken care of by try blocks.

Normally I would agree that it is good practise, however, in this case I didn't see the need. Also I thought it could possibly prevent the intended execution (correct me if I'm wrong). I'll explain what I mean:
- synchronize will run the called procedure in the main thread
- after the SP.Execute, the main thread is waiting for the call to finish
- could this not result in the progressbar standing still? (would it not wait for the main thread to finish the SP.Execute call before running?)

Regards
Pierre
0
 
LVL 1

Author Comment

by:hidrau
ID: 16381284
thanks
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Loops Section Overview
Suggested Courses
Course of the Month15 days, 12 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question