CreateEvent 多个监听器

CreateEvent multiple listeners

我正在尝试在我的应用程序的多个实例中接收一个事件。

为此,我创建了一个小型演示程序。首先是我的 TWorkerThread:

unit WorkerThreadU;

interface

uses
  WinAPI.Windows, System.Classes;

type
  TOnUpdate = reference to procedure(const Value: Integer);

  TWorkerThread = class(TThread)
  private
    FUpdate: THandle;
    FValue: Integer;
    FResult: Integer;
    FUpdateReady: TOnUpdate;
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Update;
    property Value: Integer read FValue write FValue;
    property OnUpdate: TOnUpdate read FUpdateReady write FUpdateReady;
  end;

implementation

{ TWorkerThread }

constructor TWorkerThread.Create;
begin
  inherited Create(False);
  FUpdate := CreateEvent(nil, False, False, '{B2DCFF9B-ABF7-49BA-8B7C-4F63EF20D99E}');
end;

destructor TWorkerThread.Destroy;
begin
  CloseHandle(FUpdate);
  inherited;
end;

procedure TWorkerThread.Execute;
begin
  while not Terminated do
  begin
    if WaitForSingleObject(FUpdate, 1000) <> WAIT_OBJECT_0 then
      continue;

    FResult := FValue * 2;

    if not Assigned(FUpdateReady) then
      continue;

    TThread.Queue(nil,
      procedure
      begin
        FUpdateReady(FResult);
      end);
  end;
end;

procedure TWorkerThread.Update;
begin
  SetEvent(FUpdate);
end;

end.

我的表格:

...及其来源:

procedure TfrmEvents.FormCreate(Sender: TObject);
begin
  Caption := BoolToStr(Boolean(IsDebuggerPresent), True);
  FWorkerThread := TWorkerThread.Create;
  FWorkerThread.OnUpdate := procedure(const Value: Integer)
    begin
      Log(Format('2 * %d = %d', [inpValue.Value, Value]))
    end;
end;

procedure TfrmEvents.btnCalcClick(Sender: TObject);
begin
  try
    FWorkerThread.Value := inpValue.Value;
    Log('Calculating ...');
    FWorkerThread.Update;
  finally
  end;
end;

procedure TfrmEvents.Log(const msg: string);
begin
  lbLog.ItemIndex := lbLog.Items.Add(FormatDateTime('hh:nn:ss', Now) + ' ' + msg);
end;

我的问题是只有一个实例收到事件。

程序也可以找到here

这可能是因为 CreateEvent 对所有线程实例使用相同的名称。这样所有线程都使用相同的事件。由于事件是通过自动重置创建的,第一个获得事件的线程将重置它,而其他线程则不再被注意到。

来自文档:

If this parameter is FALSE, the function creates an auto-reset event object, and system automatically resets the event state to nonsignaled after a single waiting thread has been released.