前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Delphi】 Thread.Queue与Synchronize的区别

【Delphi】 Thread.Queue与Synchronize的区别

作者头像
战神伽罗
发布2019-07-24 10:34:46
1.7K0
发布2019-07-24 10:34:46
举报

前话: 其实大家要学会看源码, 我接下来要说的这些东东,与其等别人讲,还不如自己搞几个代码试一下,印象还深刻点 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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档