gpt4 book ai didi

multithreading - Delphi-单次成功执行或通过用户取消后终止线程

转载 作者:行者123 更新时间:2023-12-03 18:31:53 25 4
gpt4 key购买 nike

新来的。对Delphi来说也是相对较新的,所以请客气...

我的实际(域)问题:小型VCL应用程序,可通过串行与两个实验室天平进行通信,以连续的1秒间隔与天平输出重量读数,称重显示在两个标签的标题中。当用户单击“称量”按钮时,我需要等待有效的重量(稳定,在范围内等)并记录一次该重量,或者允许用户取消称重。

我的问题实现了。当用户单击S.MAHDI/David Heffernan的TEvent模板的“称量”按钮时,创建一个单独的线程,如this post所示。

TWeigh = class(TThread)
private
FTerminateEvent: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(ACreateSuspended: Boolean);
destructor Destroy; override;
end;

constructor TWeigh.Create(ACreateSuspended: Boolean);
begin
FTerminateEvent := TEvent.Create(nil, True, False, '');
inherited;
end;

destructor TWeigh.Destroy;
begin
inherited;
FTerminateEvent.Free;
end;

procedure TWeigh.TerminatedSet;
begin
FTerminateEvent.SetEvent;
Beep;
end;

procedure TWeigh.Execute();
begin
while (not Terminated) do begin
if (validweight) then begin
Synchronize(procedure begin
DoStuff();
end);
end;
FTerminateEvent.WaitFor(100);
end;
end;

我的表单按钮单击事件如下所示:
{ Weigh is global implementation var of class TWeigh }
procedure TForm1.btnWeighClick(Sender: TObject);
var
B : TButton;
begin
B := Sender as TButton;
if (B.Caption = 'Weigh') then Weigh := TWeigh.Create(False);
if (B.Caption = 'Cancel') then Weigh.Free;
B.Caption := Trim(Copy('CancelWeigh ',AnsiPos(B.Caption,'Weigh Cancel'),6));
end;

这似乎可以满足取消要求。据我了解,同步消息是主线程,而主线程是执行包含DoStuff()的匿名过程的主线程,因此用户单击“取消”和输入有效权重之间不应存在竞争条件。(对吗?)

我一直在坚持如何让量重线程仅执行一次。我尝试过的各种解决方案都导致了死锁(将Weigh.Free添加到DoStuff()...并花了很长时间才弄清楚为什么THAT不起作用),单一执行但非自由线程(自我)。在if块内的syncize节之后终止,或其他各种废话。

因此,是否有可能使该线程空闲和/或杀死自己,同时仍然允许通过用户输入的父线程杀死它,还是为此我需要一个完全不同的体系结构?

针对循环的原因进行编辑:我只需要读取一个读数,但是直到获得该读数的时间在立即和从不之间变化。天平可能需要花费几秒钟来稳定,在此期间,每秒都会读取并显示不稳定的读数。仍然需要用户取消功能,因为读数可能永远无效(超重)。

最佳答案

如果我理解正确,则希望在调用DoStuff后退出线程。可以这样做:

procedure TWeigh.Execute();
begin
while (not Terminated) do begin
if (validweight) then begin
Synchronize(procedure begin
DoStuff();
end);
exit;
end;
FTerminateEvent.WaitFor(100);
end;
end;

我不得不说,这看起来比线程更适合于计时器。所有工作都在主线程上完成,并且该线程似乎只是定期检查某个标志而已。听起来像个计时器。其实为什么还要计时器呢?将标记设置为true时,为什么不触发 DoStuff

关于multithreading - Delphi-单次成功执行或通过用户取消后终止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22569623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com