delphi多线程编程4Word文档格式.docx

上传人:b****6 文档编号:16616700 上传时间:2022-11-24 格式:DOCX 页数:14 大小:297.90KB
下载 相关 举报
delphi多线程编程4Word文档格式.docx_第1页
第1页 / 共14页
delphi多线程编程4Word文档格式.docx_第2页
第2页 / 共14页
delphi多线程编程4Word文档格式.docx_第3页
第3页 / 共14页
delphi多线程编程4Word文档格式.docx_第4页
第4页 / 共14页
delphi多线程编程4Word文档格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

delphi多线程编程4Word文档格式.docx

《delphi多线程编程4Word文档格式.docx》由会员分享,可在线阅读,更多相关《delphi多线程编程4Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。

delphi多线程编程4Word文档格式.docx

 lpArgToCompletionRoutine:

Pointer;

 dwTimerLowValue:

DWORD;

 dwTimerHighValue:

DWORD

);

stdcall;

  函数名中有APC的字样,指示这是个APC函数(尽管这个名称无所谓,这是官方命名),那什么是APC函数?

  APC(AsyncroneusProcedureCall):

异步过程调用.

  原来每个线程除了有单独的消息队列,还有一个APC队列(等待执行的APC函数);

如果线程发现APC队列中有情况,马上会跳过去执行,执行完毕后才回来接着处理消息队列.

说起来麻烦,使用的时候只按上面格式传入函数指针就行;

不过能进入APC队列的回调函数和其他回调函数还有一个很大的不同:

  SetWaitableTimer按格式调用APC函数后,需要在"

当前线程"

见到一个"

等待"

此APC函数才可以进入队列.

  这好像很费解,例说一下:

APC队列有那么高的优先级,因为对资源的优先使用会对其他消息有很大的影响,肯定不能随便进入,这是不是像生活中的贵宾席或贵宾通道?

  也就是说,要进入APC队列只有SetWaitableTimer的调用还不够,还要通过"

等待函数"

介绍一下.

  WaitForSingleObject吗?

不是,它不够级别;

下面是Windows认可的、可以介绍APC入列的等待函数:

SleepEx();

WaitForSingleObjectEx();

WaitForMultipleObjectsEx();

MsgWaitForMultipleObjectsEx();

SignalObjectAndWait();

  为什么是用等待函数来把关?

因为上面几个等待函数也可以等待是否有APC函数想入列.

  上面给出的几个等待函数,就SleepEx的参数最少,先用它吧:

functionSleepEx(

 dwMilliseconds:

{毫秒数}

 bAlertable:

BOOL   {布尔值}

):

//第一个参数和Sleep的那个参数是一样的,是线程等待(或叫挂起)的时间,时间一到不管后面参数如何都会返回.

//第二个参数如果是False,SleepEx将不会关照APC函数是否入列;

//若是True,只要有APC函数申请,SleepEx不管第一个参数如何都会把APC推入队列并随APC函数一起返回.

//注意:

SetWaitableTimer和SleepEx必须在同一个线程才可以.

本例效果图:

  多线程编程(16)-多线程同步之WaitableTimer(等待定时器对象)[续二]

  代码文件:

unitUnit1;

interface

uses

 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,

 Dialogs,ExtCtrls,StdCtrls;

type

 TForm1=class(TForm)

  Button1:

TButton;

  procedureButton1Click(Sender:

TObject);

  procedureFormDestroy(Sender:

 end;

var

 Form1:

TForm1;

implementation

{$R*.dfm}

 hTimer:

THandle;

{APC函数(过程),函数名和参数名可以不同,格式必须如此}

procedureTimerAPCProc(lpArgToCompletionRoutine:

dwTimerLowValue:

DWORD);

begin

 Form1.Text:

=IntToStr(StrToIntDef(Form1.Text,0)+1);

{标题+1}

end;

procedureTForm1.Button1Click(Sender:

 DueTime:

Int64;

 hTimer:

=CreateWaitableTimer(nil,True,nil);

 DueTime:

=0;

 ifSetWaitableTimer(hTimer,DueTime,0,@TimerAPCProc,nil,False)then

 begin

  SleepEx(INFINITE,True);

{INFINITE表示一直等}

procedureTForm1.FormDestroy(Sender:

 CloseHandle(hTimer);

end.

窗体文件:

objectForm1:

TForm1

 Left=0

 Top=0

 Caption='

Form1'

 ClientHeight=113

 ClientWidth=203

 Color=clBtnFace

 Font.Charset=DEFAULT_CHARSET

 Font.Color=clWindowText

 Font.Height=-11

 Font.Name='

Tahoma'

 Font.Style=[]

 OldCreateOrder=False

 PixelsPerInch=96

 TextHeight=13

 objectButton1:

TButton

  Left=64

  Top=48

  Width=75

  Height=25

  Caption='

Button1'

  TabOrder=0

  OnClick=Button1Click

 end

end

  在上面例子中,每点一次鼠标,那个回调函数才执行一次;

作为定时器,如果想让它每秒执行一次怎么弄?

  但每一次执行那个APC函数,都得有SleepEx(当然不止它)给送进去,那这样得反复调用SleepEx才可以.

  怎么调用,用循环吗?

别说网上能找到的例子我没见到不用循环的(太笨了),就在那个APC函数里调用不就完了.

  当然这时一般要设时间间隔的,下面我们将设间隔为1000(1秒).

  但接着问题又来了,譬如把代码修改成:

 SleepEx(INFINITE,True);

{这里再次调用SleepEx}

 {下面的参数1000表示间隔1秒}

 ifSetWaitableTimer(hTimer,DueTime,1000,@TimerAPCProc,nil,False)then

任务能完成,但窗体"

死"

了...怎么办?

嘿,现在学的不是多线程吗?

  下面例子中,同时使用了CancelWaitableTimer来取消定时器,很好理解;

效果图:

  Button2:

  procedureButton2Click(Sender:

{APC函数}

{线程入口函数}

functionMyThreadFun(p:

Pointer):

Integer;

 {SetWaitableTimer必须与SleepEx在同一线程}

 Result:

 ID:

 {建立WaitableTimer对象}

 ifhTimer=0then hTimer:

 CreateThread(nil,0,@MyThreadFun,nil,0,ID);

{建立线程}

procedureTForm1.Button2Click(Sender:

 CancelWaitableTimer(hTimer);

{取消定时器}

 窗体文件:

  Left=55

  Top=32

  Width=97

  Caption=#21551#21160#23450#26102#22120

 objectButton2:

  Top=63

  Caption=#21462#28040#23450#26102#22120

  TabOrder=1

  OnClick=Button2Click

  使用APC回调函数才是WaitableTimer的正途,下次该是如何给这个函数传递参数了.

多线程编程(17)-多线程同步之WaitableTimer(等待定时器对象)[续三]。

  根据WaitableTimer的主要功用,现在再把它放在"

线程同步"

的话题中讨论有点不合适了,就要结束它.

//重新看看那个APC回调函数的格式:

 dwTimerLowValue,dwTimerHighValue:

  TimerAPCProc的后两个参数其实是在传递一个值,使用时要把它们合并为一个TFileTime类型的时间.

  这个时间是APC函数被调用的时间,稍稍修改上面一个例子看一下:

  多线程编程(17)-多线程同步之WaitableTimer(等待定时器对象)[续三]

 Dialogs,StdCtrls;

 UTCFileTime,LocalFileTime:

TFileTime;

 SystemTime:

TSystemTime;

 DateTime:

TDateTime;

 {把dwTimerLowValue与dwTimerHighValue和并为一个TFileTime格式的时间}

 UTCFileTime.dwLowDateTime:

=dwTimerLowValue;

 UTCFileTime.dwHighDateTime:

=dwTimerHighValue;

FileTimeToLocalFileTime(UTCFileTime,LocalFileTime);

{从世界标准计时到本地时间}

 FileTimeToSystemTime(LocalFileTime,SystemTime);

  {转到系统格式时间}

 DateTime:

=SystemTimeToDateTime(SystemTime);

    {再转到TDateTime}

=DateTimeToStr(DateTime);

 ClientHeight=86

 ClientWidth=256

  Left=23

  Left=134

  SetWaitableTimer中回调函数后面的指针参数,将被传递给APC函数的第一个参数;

  作为指针它可以携带任何数据,这里让它携带了一个坐标点(鼠标点击窗体的位置),下例效果图:

  procedureFormMouseDown(Sender:

TObject;

Button:

TMouseButton;

   Shift:

TShiftState;

X,Y:

Integer);

 pt:

TPoint;

{AP

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1