DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jsuguo
今日帖子: 28
在线用户: 18
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
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.
----------------------------------------------
...
作者:
男 delphiilove (乌羽玉) ★☆☆☆☆ -
普通会员
2019/11/11 23:45:29
1楼: 用 ITask
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
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 就已经被回收了。
----------------------------------------------
-
作者:
男 aknightchen (.) ★☆☆☆☆ -
盒子活跃会员
2019/11/12 11:47:35
3楼: 谢谢 pcplayer 的钻研精神和热心帮助. 我按你的解释, 测试了一下, 确实全局变量是正常的. 也谢谢你的深入解释. ( 看来, 就用全局变量来用吧...)

也谢谢 delphiilove (乌羽玉),你指点的ITask, 我发现这是另一种解决方法. (以前没用过这个) ,非常感谢!
----------------------------------------------
...
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2019/11/12 15:12:11
4楼: 楼上,TTask 是一个语法糖,简化线程的写法。

比如你有任何一个函数,需要放到线程里面去执行。如果用 TThread,代码架构会比较复杂。这时候,如果你用 TTask.Run(你的函数);一句话就搞定。

背后其实也是线程。
----------------------------------------------
-
作者:
男 doersoft (hnysoft.com) ★☆☆☆☆ -
普通会员
2019/11/12 16:32:14
5楼: 问题可能出在Windows与Android在消息处理机制上的差别.
楼主试试用SendMessage或PostMessage加上临界区来处理与界面交互试试.

一家之言.
----------------------------------------------
delphi|vue|golang hnysoft|hnyerp+mes+srm
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行62.5毫秒 RSS