Solved

Property Read Property write ??

Posted on 2004-09-25
18
350 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
Technology Partners: 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 150 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 350 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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses
Course of the Month9 days, 16 hours left to enroll

624 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