|
|
导航: |
论坛 -> 移动应用开发
斑竹:flyers,iamdream |
|
作者: |
|
2019/11/11 22:56:46 |
标题: |
小白求教: 一个极为简单的多线程例子, 为何window下正常执行, Android下,却没反映? |
浏览:1429 |
|
加入我的收藏 |
楼主: |
程序简介:
就一个form, 放一个按纽,
点击按纽时, 创建一个线程来更改按纽的Text;
TmyThread也采用完完全全的标准写法;
在Window下,可以正常运行,会更改按纽的Text 但是, 在Android上, 则点了按纽后, 没有反映;
断点跟踪,发现它有执行: TmyThread.Create; 但没有执行 TmyThread.Execute;
更为恶心的是:
当我跟踪时,如果我在TmyThread.Create;时,按F7跟踪进入, 将进入代码:TThread.Create(CreateSuspended: Boolean); 然后,在这个过程中,一步一步按F8到这个过程结尾. 然后,再按F9,就能进入到TmyThread.Execute;代码中.... (Delphi x10.3关闭,再重开,也是一样的效果--安卓无反映)
请求大侠指点,万分感谢!!!
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.Controls.Presentation, FMX.StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
TmyThread = class(TThread) private { Private declarations } procedure aaaa; protected procedure Execute; override; end;
var Form1: TForm1;
implementation
{$R *.fmx} procedure TmyThread.aaaa; begin form1.Button1.Text:='a'; end;
procedure TmyThread.Execute; begin { Place thread code here } Synchronize(aaaa); end;
procedure TForm1.Button1Click(Sender: TObject); begin TmyThread.Create; end;
end.
----------------------------------------------
... |
作者: |
|
2019/11/11 23:45:29 |
1楼: |
用 ITask
----------------------------------------------
-
|
作者: |
|
2019/11/12 11:05:33 |
2楼: |
楼主,经过反复测试,俺大概找到规律:
procedure TForm1.Button1Click(Sender: TObject); var T: TMyThread; begin T := TmyThread.Create(True); T.Start; end;
上述代码,在 TStart 那里,停一下(放一个断点,单步走),就能正确执行。如果不停,就出问题。
既然设置断点单步走停一下就有结果,那么,我测试了一下,这样写:
procedure TForm1.Button1Click(Sender: TObject); var T: TMyThread; begin T := TmyThread.Create(True); Sleep(500); T.Start; end;
加上一个 Sleep(500) 也确实有效果!
然后,我猜测,是不是局部变量离开函数就完蛋导致?
上述代码,把 T: TMyThread 的声明,放到单元的全局变量 Form1: TForm1 那里,则停不停,都没问题了。
因此,我猜,局部变量有问题,全局变量木有问题,我猜测原因是 Android 底下 Delphi 新增的垃圾自动回收 ARC 功能导致的。离开函数,函数的局部变量 T 就已经被回收了。
----------------------------------------------
-
|
作者: |
|
2019/11/12 11:47:35 |
3楼: |
谢谢 pcplayer 的钻研精神和热心帮助. 我按你的解释, 测试了一下, 确实全局变量是正常的. 也谢谢你的深入解释. ( 看来, 就用全局变量来用吧...)
也谢谢 delphiilove (乌羽玉),你指点的ITask, 我发现这是另一种解决方法. (以前没用过这个) ,非常感谢!
----------------------------------------------
...
|
作者: |
|
2019/11/12 15:12:11 |
4楼: |
楼上,TTask 是一个语法糖,简化线程的写法。
比如你有任何一个函数,需要放到线程里面去执行。如果用 TThread,代码架构会比较复杂。这时候,如果你用 TTask.Run(你的函数);一句话就搞定。
背后其实也是线程。
----------------------------------------------
-
|
作者: |
|
2019/11/12 16:32:14 |
5楼: |
问题可能出在Windows与Android在消息处理机制上的差别. 楼主试试用SendMessage或PostMessage加上临界区来处理与界面交互试试.
一家之言.
----------------------------------------------
delphi|vue|golang hnysoft|hnyerp+mes+srm
|
|