在SPComm这个串口通讯组件上封装了一个组件TWGComm,以存放私有通讯协议,这个组件有多个事件属性如
property OnRuntimeStatusEvent: TRuntimeStatusEvent read FOnRuntimeStatusEvent write FOnRuntimeStatusEvent;
property OnBrushCardEvent: TBrushCardEvent read FOnBrushCardEvent write FOnBrushCardEvent;
当SPComm的OnReceiveData事件激发后会激发上述事件处理过程。
上位程序通过procedure TWGComm.GetRunTimeStatus(equipNumber: DWORD);这个方法向串口发送指令后会激发上述事件。
我使用了多线程发送通讯指令给串口,如下线程执行方法代码:
procedure TControllerThread.Execute;
begin
{ Place thread code here }
if not Assigned(FWGComm) then begin
Suspend;
Exit;
end;
try
while (not Suspended) and (not Terminated) do begin
FSection.Acquire;
FWGComm.GetRunTimeStatus(FEquipNumber);
FSection.Release;
Sleep(300);
end;
except
on e: Exception do
WriteLog(e.Message,'Error');
end;
end;
问题是当多个线程发送指令给串口时,可能会并发激活上述事件OnRuntimeStatusEvent,OnBrushCardEvent处理过程,这样应用程序会异常,如何解决,能否使同时只有一个线程激活事件?请高手指点。
property OnRuntimeStatusEvent: TRuntimeStatusEvent read FOnRuntimeStatusEvent write FOnRuntimeStatusEvent;
property OnBrushCardEvent: TBrushCardEvent read FOnBrushCardEvent write FOnBrushCardEvent;
当SPComm的OnReceiveData事件激发后会激发上述事件处理过程。
上位程序通过procedure TWGComm.GetRunTimeStatus(equipNumber: DWORD);这个方法向串口发送指令后会激发上述事件。
我使用了多线程发送通讯指令给串口,如下线程执行方法代码:
procedure TControllerThread.Execute;
begin
{ Place thread code here }
if not Assigned(FWGComm) then begin
Suspend;
Exit;
end;
try
while (not Suspended) and (not Terminated) do begin
FSection.Acquire;
FWGComm.GetRunTimeStatus(FEquipNumber);
FSection.Release;
Sleep(300);
end;
except
on e: Exception do
WriteLog(e.Message,'Error');
end;
end;
问题是当多个线程发送指令给串口时,可能会并发激活上述事件OnRuntimeStatusEvent,OnBrushCardEvent处理过程,这样应用程序会异常,如何解决,能否使同时只有一个线程激活事件?请高手指点。
FWGComm.GetRunTimeStatus(FEquipNumber);
FSection.Release;
你在这里做了一个重要区段加锁那你还不如把FWGComm,作为FSection的成员这样保证了FWGComm不会并行触发
TControllerSection = class(TCriticalSection)
private
FWGComm: TWGComm;
public
property WGComm: TWGComm read FWGComm write FWGComm;
procedure GetRunTimeStatus(equipNumber: DWORD);
end;procedure TControllerSection.GetRunTimeStatus(equipNumber: DWORD);
begin
try
Acquire;
FWGComm.GetRunTimeStatus(equipNumber);
finally
Release;
end;
end;procedure TControllerThread.Execute;
begin
{ Place thread code here }
if not Assigned(FSection.WGComm) then begin
Suspend;
Exit;
end; try
while (not Suspended) and (not Terminated) do begin
FSection.GetRunTimeStatus(FEquipNumber);
Sleep(300);
end;
except
on e: Exception do
WriteLog(e.Message,'Error');
end;
end;