Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Property Read Property write ??

Posted on 2004-09-25
18
Medium Priority
?
351 Views
Last Modified: 2012-05-05
hi all


i have a main program that generates Threads :

...
...
...


 NewThread :=un_Process_Thread.Create(True);
 NewThread.FreeOnTerminate := True;
 NewThread.File_NO :=files_Array[i-1].File_ID; // this is who the main thread passes data to the other threads

...
...
...


no how can i read data from the thread?
i need that because i should know when the thread has finished processing ,what file was is processing and then in the main thread i should update the status of the file.


and is property read and property write helpfull in this? and if it is can any one show me a small example ?



















0
Comment
Question by:Balshe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 4
  • 2
  • +2
18 Comments
 
LVL 9

Expert Comment

by:ginsonic
ID: 12153507
Add:

   NewThread.OnTerminate        := YourVCLClass.Fine;

On this procedure can know when thread has finished processing......
0
 
LVL 1

Author Comment

by:Balshe
ID: 12153530
i know this but onterminate is used by another Procedure

NewThread.OnTerminate :=Update_LISTS;







0
 
LVL 1

Author Comment

by:Balshe
ID: 12153536
do you think there is a way to pass the parameters from the thread to the main thread other than that?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:Delphian
ID: 12153727
You could create a property or field on
the thread class and use this to get the
results.

[]s Delphian
0
 
LVL 1

Author Comment

by:Balshe
ID: 12153746
how is that?
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12154465
Hi Balshe,

It's not so safe to reach to the thread's properties like this. I would suggest you to use SendMessage API with WM_COPYDATA struct. Take a look at the accepted answers :

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20434236.html
http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20280702.html

These solutions can be usefull for you to understand the usage of WM_COPYDATA.

Regards,

Oktay Sancak
0
 
LVL 4

Expert Comment

by:Delphian
ID: 12156449
Not safe? Please elaborate, because is the first time I heard
that it is not safe to pool the threads' properties...
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12157181
Ohh maybe i gave a quick answer without to understand this question properly :( I was talking about the conditions we need to use(change/modify) the same data from the inside and outside of the thread. So i suggested something useless.. Sorry about it. OK, Now i think that i understand the question so let's take a look at this example code that i wrote for you :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  EVNT_THREAD_FINISHED = WM_USER + 7; // our custom message

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    // for to trap our custom messages which let us to know that our thread finished :
    procedure OnMyMessage(var Msg: TMessage); message EVNT_THREAD_FINISHED;
  end;

  TMyCustomThread = class(TThread)
  private
    FOwnerHandle: HWND;
  protected
    procedure Execute; override;
  public
    // some other functions, properties or procedures here
    constructor Create(AOwnerHandle: HWND);
    destructor Destroy; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.OnMyMessage(var Msg: TMessage);
begin
  Caption := 'Thread Finished';
end;

{ TMyCustomThread }

constructor TMyCustomThread.Create(AOwnerHandle: HWND);
begin
  FOwnerHandle := AOwnerHandle;
  inherited Create(True); // or False..
  FreeOnTerminate := True;
end;

procedure TMyCustomThread.Execute;
begin
  inherited;

end;

destructor TMyCustomThread.Destroy;
begin
  SendMessage(FOwnerHandle, EVNT_THREAD_FINISHED, 0, 0); // here we let our main form to know that our thread is finished running..
  inherited;
end;

end.

All the thing you need to do is :

var
  MyThread: TMyCustomThread;    
begin
  MyThread := TMyCustomThread.Create(Form1.Handle); // now your thread knows where to send the messages
  // do something
end;

Sorry about my irrelevant answer. Delphian, thanks for to wake me up :)

Kind Regards,

Oktay
0
 
LVL 1

Author Comment

by:Balshe
ID: 12157861
guys though what is above is understandable and applicable but i think what i need is more simple than this


lets say [A] is the main thread ,and [B1] is one of the threads thar are executing


on [A] there is something like :

        [A]. OnTerminate        := Run_Procedure_WITH_VARIABLES_FROM_B;


Or lets say [A] has array of record called FILES_ARRAY , and this is how the record looks like:
           File_ID:Integer
           Status:Integer;


before [A] Starts ,it gives it the value to a variable in thread [B] ; and [B] starts processing this value.
  Ex: //This is  on [A]
         [B].File_ID :=files_Array[I].File_ID;
         [B].File_INDX:=I;
         [B].OnTerminate :=Update_THREAD_COUNT;
         [B].Resume;

now when [B] finishes processing this Value ,it's gonna update it's status in the array "FILES_ARRAY" declared in [A]
 Ex:  // this is on [B]
        [A].files_array[file_INDX].Stats:=2;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
how am i supposed to declare those variables  :


     Files_Array       on[A]
     File_ID             on[B]
     File_INDX         on[B]
0
 
LVL 17

Expert Comment

by:geobul
ID: 12158357
Hi,

ceoworks code will do what you need with some little additions:

1. Pass File_ID as a parameter in SendMessage:

destructor TMyCustomThread.Destroy;
begin
  SendMessage(FOwnerHandle, EVNT_THREAD_FINISHED, File_ID, 0); // here we let our main form to know that our thread is finished running..
  inherited;
end;

2. Call 'Update_THREAD_COUNT' in procedure 'OnMyMessage' and not in Thread.OnTerminate. (Do not assign Thread.OnTerminate !)

procedure TForm1.OnMyMessage(var Msg: TMessage);
var File_ID_JustProcessed: integer;
begin
  File_ID_JustProcessed := Msg.wParam;
  Update_THREAD_COUNT(File_ID_JustProcessed); // uses File_ID_JustProcessed to update its status in the array
end;

3. Start a new thread like this:

MyThread := TMyCustomThread.Create(Form1.Handle);
MyThread.File_ID := files_Array[I].File_ID;
MyThread.File_INDX := I;
MyThread.Resume;

Hope it becomes more clear now. Using such approach looks better to me because all actions on form's controls (updating counters and changing files status) are being executed by the main thread.

Regards, Geo
0
 
LVL 1

Author Comment

by:Balshe
ID: 12158692
guys could and one send me a source code to my email ,i'm raising the points to 700
 
my email is balshe2000@yahoo.com


thanks
0
 
LVL 1

Author Comment

by:Balshe
ID: 12158729
i just found that the maximum is 500 :)
any way i could ask any question and put 200 on it






0
 
LVL 4

Assisted Solution

by:ceoworks
ceoworks earned 600 total points
ID: 12159181
Here is an example :

--------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  EVNT_THREAD_FINISHED = WM_USER + 7; // our custom message

type
  TForm1 = class(TForm)
    btnStart: TButton;
    btnTerminate: TButton;
    procedure btnStartClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnTerminateClick(Sender: TObject);
  private
    { Private declarations }
  public
    procedure OnMyMessage(var Msg: TMessage); message EVNT_THREAD_FINISHED;
  end;

  TMyThread = class(TThread)
  private
    X, Y: integer;
    FOwnerHandle: HWND;
    procedure UpdateDots;
  protected
    procedure Execute; override;
  public
    constructor Create(AOwnerHandle: HWND);
    destructor Destroy; override;
  end;

var
  Form1: TForm1;
  MyThread: TMyThread;

implementation

uses Math;

{$R *.dfm}

{ TMyThread }

constructor TMyThread.Create(AOwnerHandle: HWND);
begin
  FOwnerHandle := AOwnerHandle;
  inherited Create(False);
  FreeOnTerminate := True;
end;

destructor TMyThread.Destroy;
begin
  SendMessage(FOwnerHandle, EVNT_THREAD_FINISHED, X, Y);
  inherited;
end;

procedure TMyThread.Execute;
begin
  inherited;
  repeat
    X := Random(100);
    Y := Random(100);
    Synchronize(UpdateDots);
  until Terminated;
end;

procedure TMyThread.UpdateDots;
begin
  Form1.Canvas.Pixels[X, Y] := clRed;
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  MyThread := TMyThread.Create(Form1.Handle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MyThread.Terminate;
end;

procedure TForm1.btnTerminateClick(Sender: TObject);
begin
  MyThread.Terminate;
end;

procedure TForm1.OnMyMessage(var Msg: TMessage);
begin
  Form1.Caption := 'Thread terminated at the pixer of Y: ' + IntToStr(Msg.LParam) + ' X: ' + IntToStr(Msg.WParam);
end;

end.

--------------
0
 
LVL 4

Expert Comment

by:ceoworks
ID: 12159194
Do you need source project files too ?
0
 
LVL 1

Author Comment

by:Balshe
ID: 12159766
guys i'm really sorry ,but i'm new to Delphi
can i have an example that has two units ,one is the main thread (Main form that lunches the threads) and the other one is the thread it self?



0
 
LVL 17

Accepted Solution

by:
geobul earned 1400 total points
ID: 12161224
// main form
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  EVNT_THREAD_FINISHED = WM_USER + 7; // our custom message

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OnMyMessage(var Msg: TMessage); message EVNT_THREAD_FINISHED;
    procedure Update_THREAD_COUNT(File_ID: integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses unit2;

procedure TForm1.OnMyMessage(var Msg: TMessage);
var File_ID_JustProcessed: integer;
begin
  File_ID_JustProcessed := Msg.wParam;
  Update_THREAD_COUNT(File_ID_JustProcessed); // uses File_ID_JustProcessed to update its status in the array
end;

procedure  TForm1.Update_THREAD_COUNT(File_ID: integer);
begin
  ShowMessage('file '+ IntToStr(File_ID) + ' has been processed');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyCustomThread := TMyCustomThread.Create(Form1.Handle);
  MyCustomThread.File_ID := 7;
  MyCustomThread.File_INDX := 2;
  MyCustomThread.Resume;
end;

end.
-------------
// thread
unit Unit2;

interface

uses
  Windows, Messages, Classes;

const
  EVNT_THREAD_FINISHED = WM_USER + 7; // our custom message

type

TMyCustomThread = class(TThread)
  private
    FOwnerHandle: HWND;
  protected
    procedure Execute; override;
  public
    File_ID: integer;
    File_INDX: integer;
    constructor Create(AOwnerHandle: HWND);
    destructor Destroy; override;
  end;

var
  MyCustomThread: TMyCustomThread;

implementation

constructor TMyCustomThread.Create(AOwnerHandle: HWND);
begin
  FOwnerHandle := AOwnerHandle;
  inherited Create(True); // or False..
  FreeOnTerminate := True;
end;

procedure TMyCustomThread.Execute;
begin
  // do whatever you need here
  // ...
end;

destructor TMyCustomThread.Destroy;
begin
  SendMessage(FOwnerHandle, EVNT_THREAD_FINISHED, File_ID, 0);
  inherited;
end;

end.
-----------

Regards, Geo
0
 
LVL 1

Author Comment

by:Balshe
ID: 12167368
Thanks to you all guys

special thanks to  geobul and ceoworks




0
 
LVL 1

Author Comment

by:Balshe
ID: 12167396
ceoworks
you could collect the rest of your point on this link

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21147508.html

thanks
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Suggested Courses

721 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