【Delphi】 Thread.Queue與Synchronize的區別

前話:  其實你們要學會看源碼, 我接下來要說的這些東東,與其等別人講,還不如本身搞幾個代碼試一下,印象還深入點

TThread.Queue和TThread.Synchronize的區別,html

效果上:兩者的做用都是讓業務代碼在主線程中執行,差異: Synchronize是阻塞,Queue是非阻塞xcode

代碼上 兩個方法最終都是調用的 class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False)類方法,多線程

差異ide

Synchronize則是使用了Thread對象中的FSynchronize對象變量,而後QueueEvent爲False來調用TThread.Synchronize類方法, 函數

內部在執行FSynchronize時,建立了事件對象,經過WaitForSingleObject來阻塞執行。 .net

Queue調用是本身建立了一個PSynchronizeRecord, 而後QueueEvent爲True來調用TThread.Synchronize類方法,內部則把PSynchronizeRecord放入SyncList列表中,而後退回,並不直接執行PSynchronizeRecord, 那問題來了,在那裏執行呢?Delphi在TApplication.Idle方法中執行(最終調用了CheckSynchronize)線程

 

-----------------------------------------------------------------------------------------------------設計

Delphi中多線程用Synchronize實現VCL數據同步顯示,Delphi中多線程用Synchronize實現VCL數據同步顯示

轉自:http://blog.csdn.net/maxcode/archive/2006/05/12/726766.aspxcode

概述:        

VCL實現同步的另外一種方法就是調用線程類的Synchronize的過程,此過程須要一個無參數的procedure,故在此procedure中沒法傳遞參數值,但能夠經過類的成員來實現。在類的Execute中只須調用Synchronize就能夠了。

實現:      

         關鍵在於對Synchronize參數的定義。定義一個無參數的procedure經過它來訪問類的成員變量szName和nIndex。在類的重載Execute中調用Synchronize。子類的定義以下:
unit

TChildThread;

interfaceuses =Classes,

Messages,Windows,SysUtils;

const MAX_LEN = 260;

typeTChildThreads = class(TThread)

private      { Private declarations }protectedprocedure Execute; override;//同步函數的聲明
procedure UpdateData;

public      

szName : array[0..MAX_LEN] of Char;  

nIndex : Integer;end;implementationuses         

Unit1;

{ Important: Methods and properties of objects in VCL or CLX can only be usedin a method called using Synchronize, for example,        

Synchronize(UpdateCaption);

and UpdateCaption could look like,      

procedure TChildThread.UpdateCaption;     

begin        

Form1.Caption := 'Updated in a thread';      

end; }{ TChildThread }//同步函數的實現procedure TChildThreads.UpdateData;begin         Form1.ShowData.Items.Add(PChar(@szName));

end;

procedure TChildThreads.Execute;

begin{ Place thread code here }//調用同步過程

Synchronize(UpdateData);

end;

end.orm


主程的設計與《Delphi中多線程用消息實現VCL數據同步顯示》基本一致,但爲了與其顯示相同結果,在生成子線程中語句順序做了一下調整。如下代碼僅顯示與上一篇不一樣的一個過程,其它代碼再也不贅述。
procedure TForm1.StartThreadsClick(Sender: TObject);var         

oChildThread : array[0..1000] of TChildThreads;

i : Integer;

begin        

For i := 0 to 1000 do

begin      

oChildThread[i] := TChildThreads.Create(true);    //注意這裏的代碼與消息同步中的順序。     oChildThread[i].nIndex := i;      

strcopy(@oChildThread[i].szName,PChar('Child' + IntToStr(i)));      

oChildThread[i].Resume;

end;

end;

===============================================

另外一個例子:http://topic.csdn.net/t/20011015/02/323001.html

   unit    Unit1;  
   
   interface  
   
   uses  
       Windows,    Messages,    SysUtils,    Variants,    Classes,    Graphics,    Controls,    Forms,  
       Dialogs,    StdCtrls,    ExtCtrls;  
   
   type  
       TForm1    =    class(TForm)  
           Button1:    TButton;  
           Edit1:    TEdit;  
           Image1:    TImage;  
           procedure    Button1Click(Sender:    TObject);  
       private  
           {    Private    declarations    }  
       public  
           {    Public    declarations    }  
       end;  
   
       TMyThread    =    class(TThread)  
       private  
           child    :    TComponent;  
   
       public  
           procedure    draw;  
           constructor    Create(parent    :    TComponent);  
           procedure    Execute;    override;  
   
       end;  
   
   var  
       Form1:    TForm1;  
   implementation  
   
   {$R    *.dfm}  
   
   {    TMyThread    }  
   
   constructor    TMyThread.Create(parent:    TComponent);  
   begin  
       child    :=    parent;  
       inherited    Create(false);  
   end;  
   
   procedure    TMyThread.draw;  
   begin  
       if    (child    is    TEdit)    then  
       begin  
           (child    as    TEdit).Text    :=    'OK';  
       end  
       else    if(child    is    TImage)    then  
       begin  
           (child    as    TImage).Canvas.Brush.Color    :=    clBlue;  
           (child    as    TImage).Canvas.FillRect(rect(0,0,100,100));  
       end;  
   end;  
   
   procedure    TMyThread.Execute;  
   begin  
       inherited;  
       synchronize(draw);  
       if    Terminated    then    Exit;  
   end;  
   
   procedure    TForm1.Button1Click(Sender:    TObject);  
   
   begin  
       TMythread.Create(Edit1);  
       TMythread.Create(image1);  
   end;

http://blog.csdn.net/jiangnanandi/article/details/2962925

相關文章
相關標籤/搜索