正确使用匿名线程

//你可能会遇到典型的“线程”话题,现在是新世代的Delphi编程,不再是“D7年代”了,一定要养成随时随地想着使用线程的习惯...... : 
function TAppIDAndUserAccount.setAppID(
  const cnstr, ASql: string): Boolean;
var
  LEvent:TEvent;//:信号灯:控制线程执行行为的局部变量;
  LResult:Boolean; LResultInt:Integer;  //:它们都可以作为线程的返回值,可简单的用来控制线程的执行行为,未正常或成功地执行完毕!
begin
  LResultInt:=0;
 
  LEvent :=TEvent.Create(true);
    //true:即:UseCOMWait(主要Windows下用,其它平台设置了也会对这个参数的传入置之不理):
    //指定UseCOMWait以确保在线程对象处于阻塞态时等待任何STA-COM都可以做回调到该线程
    //什么是STA-COM:
//1、在内存层面STA指,Spike-triggered average,译做“发放-触发平均方法”。表示传送地址指令。
//2、在进程层面STA指,Single-threaded apartment,单线程单元,是在WINDOWS系统中程序运行的一种方式。3、在芯片层面STA指,Static Timing Analysis,静态时序分析,是芯片设计中的一个后端流程,通常对设计的电路的时序路径进行分析,区别与动态逻辑分析。详见:https://baike.baidu.com/item/STA/4561221?fr=aladdi
TThread.CreateAnonymousThread( procedure var LResultmsg:string; begin try try //在这里写线程执行函数的代码...: //调sql:执行一条sql语句: //where条件like必须ltrim(rtrim(去空否则含有全角等查不出来: if SQL(ASql,LResultmsg,nil,cnstr)=true then begin LResultInt:=1; LResult :=true; TThread.Synchronize(nil, procedure //var LEtc:string; UI同步局部变量; begin //在这里写线程执行函数结束后与UI的交互...: SJGY.ToastConfirm('已为您生成试用账号的AppID',(FOwner as TForm),2.5); end);//:若不发出UI消息,是因为类未实例化其FOwner(constructor Create) //Application.ProcessMessages;//:{$IFDEF CLR}用了线程同步就不必用它了;它通常对.net有意义(老版本delphi.net继承下来可用的) end else begin LResult :=false; LResultInt:=1; //Application.ProcessMessages;//:{$IFDEF CLR}用了线程同步就不必用它了;它通常对.net有意义(老版本delphi.net继承下来可用的)//SJGY.ToastConfirm........ TThread.Synchronize(nil, procedure //var LEtc:string; UI同步局部变量; begin //线程异常:在这里写与UI的交互...: SJGY.ToastConfirm('代码异常或网络超时,发生在写数据库CarveoutAppID表CustomerAppID的过程中:' +LResultmsg,(FOwner as TForm),2.5); end); LEvent.SetEvent; LEvent.DisposeOf; end; except LResultInt:=1; LResult :=false; //Application.ProcessMessages;//:{$IFDEF CLR}用了线程同步就不必用它了;它通常对.net有意义(老版本delphi.net继承下来可用的)//SJGY.ToastConfirm........ TThread.Synchronize(nil, procedure //var LEtc:string; UI同步局部变量; begin //线程异常:在这里写与UI的交互...: SJGY.ToastConfirm('线程异常或网络超时:发生在写数据库CarveoutAppID表CustomerAppID的过程中',(FOwner as TForm),2.5); end); LEvent.SetEvent; LEvent.DisposeOf; end; finally LResultInt:=1; LResult :=true; LEvent.SetEvent; LEvent.DisposeOf; end; end).Start; while LResultInt=0 do LEvent.ResetEvent; //无论线程是否执行成功或发生异常,都可LEvent.ResetEvent通过强制其返回值LResultInt:=1; //这是强制等待线程结束的方法,请根据具体使用场景合理使用...... Result:=LResult; //注意:LEvent.SetEvent仅仅通知UI线程执行函数的代码已经执行完毕, //但若是长耗时的线程,它可能并未结束和被释放,交由delphi的线程库来控制,//:操作系统本身并不直接管控用户态的线程,它只管控操作系统内核态的线程 //也可交由被调用的窗体的Close事件Action := TCloseAction.caFree来释放 //线程自己是不能释放自己的,只能通过UI组件的事件来释放(这跟线程常用的5个状态有关) //但是当长耗时的线程正在执行,你却强行释放它,则会内存泄漏: //所以,所有非主窗体Close事件都不要caFree, //把它留给主窗体Application组件来管理delphi的线程库,所有非主窗体的Owner设置为Application end;

原文地址:

https://blog.csdn.net/pulledup/article/details/108139748

原文地址:https://www.cnblogs.com/kinglandsoft/p/14970810.html