Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1667
  • Last Modified:

wait for PostThreadMessage to finish

i have some code, then somewhere in the middle, i call postThreadMessage to run something in a thread.
i can't really put the code inline... so how can i want for postThreadMessage to finish before going onto the next lines?
0
gwarguitar
Asked:
gwarguitar
  • 5
  • 3
1 Solution
 
Slick812Commented:
the whole purpose of the  postThreadMessage(  )  function is to NOT WAIT for the code in that thread to be processed, it is meant to be used when you can NOT wait for the other thread to work. . . if you need to have the other thread finish working,  you might try using the standard   SendMessage(  ) function to wait for it to return
0
 
gwarguitarAuthor Commented:
hmm... can i use sendMessage when trying to send messages inside a thread created with BeginThread?
0
 
Russell LibbySoftware Engineer, Advisory Commented:

If the thread you are communicating with does not have an a assoicated window, then you will not be able to use the SendMessage api. (which requires a window handle). There is no SendThreadMessage api either, but if you have control (source code) for both threads, then you could:

1.) have the calling thread create a non-signled event (using CreateEvent)
2.) pass this as a param to the the recv'ing thread
3.) WaitForSingleObject on this event, thus suspending until the recv'ing thread has signaled the event

The recv'ing thread should then signal this event when it has completed whatever it is it needs to do. This would give you the same effect as SendMesage does with window handles.

Regards,
Russell


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!

 
gwarguitarAuthor Commented:
could i see a createEvent example with postThreadMessage; not a lot of english results coming up on google! :)
0
 
Slick812Commented:
I should have explained more in my last comment?
If I need to set up some communication between threads, I will create a Thread with an invisable window running in it to get and use messages, and then I can do thread  communication without using Syncronize, or Wait stuff, which can be trouble to deal with sometimes. . .
0
 
Slick812Commented:
seems like you could do this more better with  a notify type of message back to the form or main window?
anyway, heres my version of a wait for a message


code in the Thread -
while GetMessage(Msg1,0,MsgToThread,MsgToThread) do
    begin
    if Msg1.wParam = 621 then
      begin
      Sleep(2000);
      SetEvent(Msg1.LParam); // need to read the LParam for hEvent
      end;
    end;

// you could use PeekMessage instead, but you have no reference to you code methods


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

button click for to wait on message

procedure TForm1.sbut_WaitThreadMsgClick(Sender: TObject);
var
hEvent, WaitRe: Cardinal;
Str1: String;
begin
if IDThread = 0 then
  begin
  ShowMessage('Thread Not Running');
  Exit;
  end;
hEvent := CreateEvent(nil,True,False,nil);
PostThreadMessage(IDThread, MsgToThread, 621, hEvent);
WaitRe := WaitForSingleObject(hEvent, 4000);
CloseHandle(hEvent);
if WaitRe = WAIT_OBJECT_0 then
  Str1 := 'Thread Wait was successfull'
  else
  Str1 := 'Thread Wait FAILED';
ShowMessage(Str1);
end;


- - - - - - - - - - - - - - - - - -  --
hope ths helps?
But I would not like to freeze up my main thread for a Thread to work on some data.
you might give Russel the points since he suggested this
0
 
Slick812Commented:
here is some more code you may can get some Ideas from,  I'm not certain how you implement your thread? or anything else about what you may be doing or method in yout thread, do you use the Delphi  TThread?
anyway- - here is some code for a thread that can send messages  to the Form to tell it when thread processing work is done, and then the Form thread can read the data sent to it and use it without Freezing up the main thread with a WaitRorSingleObject

const
  MsgToThread = WM_USER + 1230;
  MsgFromThread = WM_USER + 1231;


type
  PWorkRec = ^TWorkRec;
  TWorkRec = record
    FormHandle: THandle;
    WorkID: Integer;
    Work: TPoint;
    Signal: String;
    end;

  PSendData = ^TSendData;
  TSendData = record
    WorkID: Integer;
    Message: String;
    WorkResult: TPoint;
    end;

// thei private is for the Form1 and has the  MsgFromThread message
  private
    { Private declarations }
    procedure MsgThread(var Msg : TMessage); message MsgFromThread;

implementation

var
IDThread: Cardinal = 0;
hThread2: THandle;


procedure TForm1.MsgThread(var Msg: TMessage);
begin // recieves the messages from the thread
case Msg.WParam of
  11: ShowMessage('Work Thread '+IntToStr(Msg.LParam)+' has started');
  22: ShowMessage('Thread Work Result is '+IntToStr(Msg.LParam));
  33: begin
    with PSendData(Msg.LParam)^ do
      ShowMessage(Message+' '+IntToStr(WorkResult.x));
    Dispose(Pointer(Msg.LParam));
    end;
  44: ShowMessage('Work Thread is Finished');
  end;
end;



function ThreadFunc(pWork1: PWorkRec): Integer;
// if you are using the TThread this would be the "Execute" procedure
var
Msg1: TMSG;
WorkResult: Integer;
pSend: PSendData;
begin
Result := 0;

if pWork1.WorkID = 654 then
  begin
  PostMessage(pWork1.FormHandle, MsgFromThread, 11, pWork1.WorkID);
  Sleep(3000); // doing work
  WorkResult := pWork1.Work.x + pWork1.Work.y;
  PostMessage(pWork1.FormHandle, MsgFromThread, 22, WorkResult);
  while GetMessage(Msg1,0,MsgToThread,MsgToThread) do
    begin
    if Msg1.wParam = -555 then PostQuitMessage(0);
    if Msg1.wParam = 14 then
      begin
      New(pSend); // I use the New( ) to send data to another thread so I will not need to Syncronize it
      pSend.WorkID := pWork1.WorkID;
      pSend.Message := pWork1.Signal+' 14 work is done';
      pSend.WorkResult.x := pWork1.Work.x + 2000;
      PostMessage(pWork1.FormHandle, MsgFromThread, 33, Integer(pSend));
      end;
    if Msg1.wParam = 621 then
      begin
      Sleep(2000);
      SetEvent(Msg1.LParam);
      end;
    end;
  end;
PostMessage(pWork1.FormHandle, MsgFromThread, 44, 0);
Dispose(pWork1);
IDThread := 0;

EndThread(Result);
end;



procedure TForm1.sbut_BeginThreadClick(Sender: TObject);
var
pWork11: PWorkRec;
begin
if IDThread <> 0 then
  begin
  ShowMessage('Thread is Already Running');
  Exit;
  end;

New(pWork11);
with pWork11^ do
  begin
  FormHandle := Handle;
  WorkID := 654;
  Work.x := 1000;
  Work.y := 23;
  Signal := 'Today';
  end;

hThread2 := BeginThread(nil, 0, @ThreadFunc, pWork11, 0, IDThread);
end;

procedure TForm1.sbut_ThreadMsgClick(Sender: TObject);
begin
if IDThread = 0 then
  begin
  ShowMessage('Thread Not Running');
  Exit;
  end;
// this is the message to send to tell the thread to do work, you do not wait here
PostThreadMessage(IDThread, MsgToThread, 14,0);
//after the thread work is done for this "14" message, a message is sent to the Form, to tell it it has done the work
end;

procedure TForm1.sbut_KillThreadClick(Sender: TObject);
begin // this will end the thread
if IDThread = 0 then
  begin
  ShowMessage('Thread Not Running');
  Exit;
  end;
PostThreadMessage(IDThread, MsgToThread, -555,0);
end;

procedure TForm1.sbut_WaitThreadMsgClick(Sender: TObject);
var
hEvent, WaitRe: Cardinal;
Str1: String;
begin
if IDThread = 0 then
  begin
  ShowMessage('Thread Not Running');
  Exit;
  end;
hEvent := CreateEvent(nil,True,False,nil);
PostThreadMessage(IDThread, MsgToThread, 621, hEvent);
WaitRe := WaitForSingleObject(hEvent, 4000);
CloseHandle(hEvent);
if WaitRe = WAIT_OBJECT_0 then
  Str1 := 'Thread Wait was successfull'
  else
  Str1 := 'Thread Wait FAILED';
ShowMessage(Str1);
end;
0
 
gwarguitarAuthor Commented:
no, i don't use TThread, i create it api
0
 
Slick812Commented:
reference sources (delphi Help and others) say that using  BeginThread( ) is better (more safe) than the API  CreateThread( ) for Delphi
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now