//你可能会遇到典型的“线程”话题,现在是新世代的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=aladdin
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