Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anyway to know the status of a TEvent?

Tags:

delphi

I have several threads, each with its own TEvent:

  TWorkerThread = class(TThread)
  private
    FSignal: TEvent;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Execute; override;
  end;

procedure TWorkerThread.Execute;
var ID: integer;
begin

  while not Terminated do begin

    Tmonitor.Enter(MainQueue);
    try
      if (MainQueue.Count > 0) then ID := MainQueue.dequeue
      else ID := 0;
    finally
      Tmonitor.exit(MainQueue);
    end;

    if (ID <> 0) then ProcessID(ID)
    else fSignal.WaitFor(INFINITE);

  end;

end;

Now, in the main thread I would like to retrieve the list of threads that are waiting for the signal, so those who are doing fSignal.WaitFor(INFINITE);

Actually I do like this in the code:

procedure AddIDToTheQueue(const id: integer);
begin

  Tmonitor.Enter(MainQueue);
  try

    MainQueue.Enqueue(id);

    //signal all background thread !!! this a don't like i prefer to signal only one thread who are waiting instead of signaling all the threads !!!
    for I := Low(workerThreads) to High(workerThreads) do
      workerThreads[i].Signal.SetEvent;

  finally
    Tmonitor.Exit(MainQueue);
  end;

end;

but it's not efficient as I signal all threads instead of signalling only the first one that is waiting for the signal. How can I do this?

like image 838
zeus Avatar asked Dec 14 '25 01:12

zeus


1 Answers

To directly answer your question, you can always check if an event is signalled using :

 if FSignal.WaitFor(0) = wrSignaled then begin
   // event is signaled
 end;

If you need to handle all cases, of course :

case FSignal.WaitFor(0) of
  wrSignaled:;
  wrTimeout:;
  wrAbandoned:;
  wrError:;
  wrIOCompletion:;
end;

However - this is an ideal situation to leverage the built-in threadpool by simply using tasks.

For example, all of your code can be eliminated and reduced to this :

procedure AddIDToTheQueue(id: integer);
var
  LTask : ITask;
begin
  LTask := TTask.Create(procedure begin ProcessID(id); end);
  LTask.Start;
end;

There is no sense in passing an integer as const. Whether you pass the value or a pointer, it's the same size. If you're not modifying it, it makes no difference.

like image 110
J... Avatar answered Dec 16 '25 23:12

J...



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!