将事件从主线程传递给工作线程并等待它是否安全?

时间:2012-03-02 15:40:25

标签: multithreading delphi events thread-safety delphi-xe2

我正在处理这种动作队列线程,我想等待某个动作执行。我想在主线程中创建操作,然后将其传递给队列线程函数(到队列的末尾)并等待执行此操作。所以我需要区分我刚刚查询过的动作并等待它。

我有以下(伪)代码,我想知道

  • 是否使用Windows事件对象线程安全?
  • 如果是,这个概念会有效吗?

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;

谢谢!

2 个答案:

答案 0 :(得分:4)

是的,这完全没问题。从CreateEvent返回的句柄可以被所有线程自由使用。任何其他东西都会使它变得毫无用处,因为这是它的主要用途:)

答案 1 :(得分:3)

不要等待GUI事件处理程序中的线程。不要等待事件,信号量或互斥,sleep()循环,DoEvents循环或其任何组合。

如果要与主线程通信以表示已在线程池中处理了某些内容,请查看PostMessage()API。