Martin Reiner
Martin Reiner

Reputation: 2197

Is it safe to pass the event from the main thread to the worker thread and wait for it?

I'm working on such kind of an action queue thread and I would like to wait for a certain action to be performed. I'd like to create the action in main thread, then pass it to the queue thread function (to the end of the queue) and wait for this action to be performed. So I need to distinguish the action I have just queried has been performed and wait for it.

I have a following (pseudo) code and I would like to know


type
  TMyThread = class(TThread);
  private
    FEvent: THandle;
  protected
    procedure Execute; override;
  public
    procedure DoSomething(const AEvent: THandle);
  end;

procedure TMyThread.Execute;
begin
  //  is it working with events thread safe ?
  SetEvent(FEvent);
  //  the thread will continue, so I can't use WaitFor
  //  but it won't set this specific FEvent handle again
  //  I'm working on such kind of an action queue, so once the action with ID,
  //  here represented by the FEvent will be processed, it's removed from 
  //  the action queue
end;

procedure TMyThread.DoSomething(const AEvent: THandle);
begin
  FEvent := AEvent;
end;

//  here's roughly what I want to do

procedure TForm1.Button1Click(Sender: TObject);
var
  OnceUsedEvent: THandle;
begin
  //  the thread is already running and it's instantiated in MyThread
  //  here I'm creating the event for the single request I need to be performed
  //  by the worker thread
  OnceUsedEvent := CreateEvent(nil, True, False, nil);
  try 
  //  here I'm passing the event handle to the worker thread (like a kind of
  //  a request ID)
    MyThread.DoSomething(OnceUsedEvent);
  //  and here I want to wait for 10 seconds (and also interrupt this waiting 
  //  when the user closes the application if possible ?) for the thread if
  //  performs my request
    WaitForSingleObject(OnceUsedEvent, 10000);
  finally
  //  close the event handle
    CloseHandle(OnceUsedEvent);
  end;
  //  and continue with something else
end;

Thanks!

Upvotes: 5

Views: 1122

Answers (2)

Martin James
Martin James

Reputation: 24887

Do not wait for threads in GUI event handlers. Don't do it by waiting on events, semaphores or mutexes, sleep() loops, DoEvents loops or any combination thereof.

If you want to communicate with the main thread to signal that something has been processed in a threadpool, look at the PostMessage() API.

Upvotes: 3

Yes, that is perfectly fine. The handle returned from CreateEvent can be freely used by all threads. Anything else would render it pretty useless since this is its primary use :)

Upvotes: 4

Related Questions