正確使用匿名線程


//你可能會遇到典型的“線程”話題,現在是新世代的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM