gpt4 book ai didi

multithreading - Delphi Threading/PPL-在TTask.Run或TThread.CreateAnonymousThread中将Timer.Enabled设置为True后,永远不会触发OnTimer事件

转载 作者:行者123 更新时间:2023-12-03 13:22:49 29 4
gpt4 key购买 nike

在使用线程/PPL增强企业FMX应用程序的性能时,我遇到了一些问题,但是找不到解释。这是一个简化的程序,用于显示问题所在:
表单内容

object Form1: TForm1
FormFactor.Devices = [Desktop]
object Label1: TLabel
Text = 'Time'
end
object Label2: TLabel
Text = 'Timer state'
end
object Button1: TButton
Text = 'Start (Normal)'
OnClick = Button1Click
end
object Button2: TButton
Text = 'Start (Task)'
OnClick = Button2Click
end
object Button3: TButton
Text = 'Start (AnonymThread)'
OnClick = Button3Click
end
object Timer: TTimer
Enabled = False
OnTimer = TimerTimer
end
end
格式代码
unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Timer: TTimer;
procedure TimerTimer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.fmx}

uses System.Threading;

procedure TForm1.Button1Click(Sender: TObject);
begin
Timer.Enabled:= False;
Label1.Text:= 'Time (Normal)';

Timer.Enabled:= True;
Label2.Text:= 'Timer ON (Normal)';

// Result: All above and OnTimer OK

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Timer.Enabled:= False;
Label1.Text:= 'Time (Task)';

TTask.Run(
procedure
begin
Timer.Enabled:= True;
Label2.Text:= 'Timer ON (Task)';
end);

// Result: All above OK but no OnTimer

end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Timer.Enabled:= False;
Label1.Text:= 'Time (AnonymThread)';

TThread.CreateAnonymousThread(
procedure
begin
Timer.Enabled:= True;
Label2.Text:= 'Timer ON (AnonymThread)';
end).Start;

// Result: ThreadProc may/may not fully run (But Timer.Enabled:= True seems always executed) and no OnTimer

end;

procedure TForm1.TimerTimer(Sender: TObject);
begin
Label1.Text:= DateTimeToStr(Now);
end;

end.
注意:在每个按钮的OnClick中,我都写了相应的结果。
Delphi的任何程序员都可以帮助我理解为什么以及可能做什么(当然,使用线程/PPL)吗?先感谢您。

最佳答案

多线程的基本规则之一是,您不得从非GUI线程与GUI进行交互。
这包括放置在表单上的计时器。例如,在Microsoft Windows上,启用计时器将调用 SetTimer 。在FMX中,此计时器是通过回调过程设置的。因此,文档的以下部分是相关的:

When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.


您的 OnTimer事件未触发,因为您的新线程未调度消息。您需要重新设计系统。特别是,请勿触摸非GUI线程的基于GUI的计时器。并且不要触摸任何类似 TLabel的控件。

关于multithreading - Delphi Threading/PPL-在TTask.Run或TThread.CreateAnonymousThread中将Timer.Enabled设置为True后,永远不会触发OnTimer事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66078132/

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