【发布时间】:2016-09-10 13:45:34
【问题描述】:
我目前正在开发一个定期执行一些 AT 命令的程序。 我试图让它多线程,因为这个程序应该同时与 8 个 GSM 调制解调器一起工作。 这是我作为 TWorkerThread 扩展的 TThread 类:
TWorkerThread = class(TThread)
private
FThreadJob : TThreadJobs;
FSimNum : Word;
FZylGSM : TZylGSM;
SL_AT : TStringList;
FSignalGauge : TsGauge;
procedure SyncProc;
public
TerminateThread : Boolean;
constructor Create;
property ThreadJob : TThreadJobs read FThreadJob write FThreadJob;
property ZylGSM : TZylGSM read FZylGSM write FZylGSM;
property SimNum : Word read FSimNum write FSimNum;
property SignalGauge: TsGauge read FSignalGauge write FSignalGauge;
protected
procedure Execute; override;
end;
我的线程方法的主体:
constructor TWorkerThread.Create;
begin
inherited Create(True);
if Not Assigned(SL_AT) then SL_AT := TStringList.Create;
SL_AT.Clear;
FThreadJob := tjNone;
TerminateThread := False;
FreeOnTerminate := True;
end;
procedure TWorkerThread.Execute;
begin
inherited;
if FThreadJob = tjNone then Exit;
while TerminateThread=False do Synchronize(SyncProc);
end;
procedure TWorkerThread.SyncProc;
var
ts : String;
SignalStrength : Byte;
begin
if bTerminateFlag then TerminateThread := True;
if TerminateThread then Exit;
case FThreadJob of
tjOperatorName : ;
tjSignalQuality :
begin
FZylGSM.ExecuteATCommand('AT+CSQ', SL_AT);
if (SL_AT.Count>2) And (Pos('OK', SL_AT[2])>0) then begin
ts := Copy(SL_AT[1], Pos(':', SL_AT[1])+1, Length(SL_AT[1]));
ts := Trim(ts);
if ts = '99' then ts:='0';
SignalStrength := StrToIntDef(ts, 0);
SignalGauge.Progress := SignalStrength;
end;
if bTerminateFlag then TerminateThread := True;
// Application.ProcessMessages;
end;
end;
end;
我使用 for 循环创建了 8 个这样的线程:
DevPorts.GSM_Ports[i].WorkerThread := TWorkerThread.Create;
DevPorts.GSM_Ports[i].WorkerThread.ThreadJob := tjSignalQuality;
DevPorts.GSM_Ports[i].WorkerThread.SimNum := i+1;
DevPorts.GSM_Ports[i].WorkerThread.SignalGauge := FindComponent('Sig_'+IntToStr(i)) as TsGauge;
DevPorts.GSM_Ports[i].WorkerThread.ZylGSM := DevPorts.GSM_Ports[i].Comm;
DevPorts.GSM_Ports[i].WorkerThread.Start;
当我评论“Application.ProcessMessages”时程序按预期工作,问题是当我在“TWorkerThread.SyncProc”中使用“Application.ProcessMessages”时,我的一些线程没有执行。我知道在线程函数中使用 ProcessMessage 可能是错误的,但我这样做是因为主 GUI 线程在线程的发送/接收期间挂起。
任何帮助将不胜感激。
【问题讨论】:
-
您的参赛作品设计是假的。所有工作都在主线程中执行。删除所有线程代码并在主线程中完成工作。或者使用线程并在线程中完成工作。是的,ProcessMessages 是个坏主意。永远不要使用它。
-
@DavidHeffernan 感谢您的评论。正如我所提到的,我必须同时对每个 GSM 调制解调器进行发送/接收。所以,我不能在主线程中完成所有工作。您能否告诉我为什么所有工作都在我的代码的主线程中执行?
-
因为您使用了 Synchronize。你的代码有很多问题。 Stack Overflow 并不是真正的调试个人代码。它是关于对其他人有用的一般问题和答案。
标签: multithreading delphi delphi-10-seattle