【Delphi】 Thread.Queue与Synchronize的区别

2019-07-24 10:34:46 浏览数 (1)

前话: 其实大家要学会看源码, 我接下来要说的这些东东,与其等别人讲,还不如自己搞几个代码试一下,印象还深刻点 TThread.Queue和TThread.Synchronize的区别,

效果上:二者的作用都是让业务代码在主线程中执行,差别: Synchronize是阻塞,Queue是非阻塞

代码上 两个方法最终都是调用的 class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False)类方法,

差别

Synchronize则是使用了Thread对象中的FSynchronize对象变量,然后QueueEvent为False来调用TThread.Synchronize类方法,

内部在执行FSynchronize时,创建了事件对象,通过WaitForSingleObject来阻塞执行。

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.aspx

概述: 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.

主程的设计与《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

0 人点赞