DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: cuiqingbo
今日帖子: 25
在线用户: 11
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 sxfgf (FC_FGF) ★☆☆☆☆ -
普通会员
2023/3/6 18:28:49
标题:
追问一下,多线程的疑问 浏览:949
加入我的收藏
楼主: uses System.Threading


procedure XXXX;
var  Mythreadtask : ITask;
begin
 if Assigned(Mythreadtask) then
  begin
      if Mythreadtask.Status = TTaskStatus.Running then
      begin
      //If it is already running don't start it again
          Exit;
      end;
  end;
 Mythreadtask := TTask.Create (procedure ()
 var I:integer;
  begin
    //////////
      需要执行的代码
    //////////
   end);
   Mythreadtask.Start;
end;

当一个form中需要多次使用线程时,发现:
比如:在线程里执行完下述:
 ClientModule1.ClientDataSet1.Close;
 ClientModule1.ClientDataSet1.CommandText:='select XXX  from  XXX';
 ClientModule1.ClientDataSet1.Open;
后,在其他的功能里,执行查询:(没放到线程里)
 ClientModule1.ClientDataSet1.Close;
  ClientModule1.ClientDataSet1.CommandText:='select a1,a2,a3  from  XXX';
 ClientModule1.ClientDataSet1.Open;
 if ClientModule1.clientDataSet1.recordcount >0 then
begin
  //这里可以查询到recordcount>0
  但是:
 变量:= ClientModule1.ClientDataSet1.FieldByName('a1').AsString;

  //这里就出错了,提示ClientDataset not  fount a1
end;


然后 Try 语句就直接跳过了后边的代码

最后,我把 Mythreadtask.Start;    改成:Mythreadtask.ExecuteWork;
至少是可以正常查询了

请问:线程的Start  与  ExecuteWork  有啥区别呢?
----------------------------------------------
偶尔做做代码应付一下工作,却发现Delphi已成必配
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2023/3/6 19:44:54
1楼: 你将整个ClientModule在Task里创建,不要和外面共用
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/3/6 22:40:05
2楼: pay attention:

1) any "ERROR" = Access Violation, Exception, etc... into a "thread" do stop it!!!!

then, you need always use "TRY... EXCEPT... END"

2) dont use "share any db component in thread and main-thread"... 

3) if needs updates de UI, use:
 a) xx.Synchronize(...) = for try update "imediatelly"
 b) xx.Queue(...)       = for try update "when possible"

try this way:

procedure ThreadXXXXX.WWWWWW
var
  myQry:TxxxQuery;
  // + vars
begin
  myQry:TxxxQuery.create....;
  try
    try
    /// + code
    qry.Open....
     /// + code
    qry.Close;
    except
      // ? ? ? ?
    end;
  finally
    myQry.Free;
  end; 
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2023/3/7 21:10:08
3楼: 楼主,你的问题,我猜,既然是 ClientdataSet,那么,多半绑定了界面控件。

比如有一个 DBGrid - DataSource -你的 ClientDataSet

如果有这样的情况,那么,你把 ClientDataSet 的操作放到线程里面,就等于用线程操作界面。

用线程操作 UI 界面元素,是会出问题的。而且是奇怪问题。有时候它好像又没事。

你先排除这种情况吧。
----------------------------------------------
-
作者:
男 comeheres (tomorrow) ▲▲▲▲▲ -
普通会员
2023/3/8 10:34:19
4楼: Start是异步执行,它会将任务加入到线程池中异步执行,不会阻塞当前线程,并返回一个 ITask 接口。ExecuteWork是Delphi 10.4版本开始新增的,同步执行一个线程任务,会阻塞主线程,直到线程任务执行完成并返回
----------------------------------------------
业余编程爱好者
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行62.5毫秒 RSS