【问题标题】:CreateEvent multiple listenersCreateEvent 多个监听器
【发布时间】:2022-01-06 11:19:14
【问题描述】:

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

为此,我创建了一个小型演示程序。首先是我的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找到。

【问题讨论】:

    标签: multithreading delphi event-handling delphi-xe2


    【解决方案1】:

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

    来自文档:

    如果此参数为 FALSE,该函数创建一个自动复位事件 对象,系统自动将事件状态重置为无信号 在一个等待线程被释放后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多