Безопасно ли передавать событие из основного потока в рабочий поток и ждать его? - PullRequest
5 голосов
/ 02 марта 2012

Я работаю над таким потоком очереди действий и хотел бы дождаться выполнения определенного действия.Я хотел бы создать действие в главном потоке, затем передать его функции потока очереди (до конца очереди) и дождаться выполнения этого действия.Поэтому мне нужно различить только что запрошенное действие и дождаться его.

У меня есть следующий (псевдо) код, и я хотел бы знать, действительно ли это

  • работать с потоком объектов событий 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 ]

4 голосов
/ 02 марта 2012

Да, это прекрасно. Дескриптор, возвращаемый из CreateEvent, может свободно использоваться всеми потоками. Все остальное сделало бы его довольно бесполезным, так как это его основное использование:)

3 голосов
/ 02 марта 2012

Не ждите потоков в обработчиках событий GUI. Не делайте этого, ожидая событий, семафоров или мьютексов, циклов sleep (), циклов DoEvents или любой их комбинации.

Если вы хотите связаться с основным потоком, чтобы сообщить, что что-то было обработано в пуле потоков, посмотрите на API PostMessage ().

...