• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Delphi多线程学习(7):事件Event

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Event事件用法与Mutex差不多,但它可以使用:SetEvent(启动运行)ResetEvent(暂停运行)、PulseEvent(执行一次后立即暂停)。

       先看一下创建函数:CreateEvent(
                                       lpEventAttributes: PSecurityAttributes;
                                       bManualReset: BOOL;    
                                       bInitialState: BOOL; 
                                       lpName: PWideChar ): THandle; stdcall;

(lpEventAttributes参数,指向TSecurityAttributes记录的指针,一般可以缺省填入nil值;

   bManualReset参数,是否可手动暂停,True为可手动,False为事件对象控制一次后将立即暂停;

   bInitialState参数,初始状态,True为事件对象创建后处可运行状态,False为暂停状态;

   lpName参数,事件的名称;

   返回值为句柄。)

例子代码:

{主窗体代码}  
  1. unit Unit2;  
  2.    
  3. interface  
  4.    
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls;  
  8.    
  9. type  
  10.   TForm2 = class(TForm)  
  11.     Button1: TButton;  
  12.     Label1: TLabel;  
  13.     Label2: TLabel;  
  14.     Label3: TLabel;  
  15.     Label4: TLabel;  
  16.     Label5: TLabel;  
  17.     btnSetEvent: TButton;  
  18.     btnResetEvent: TButton;  
  19.     btnPulseEvent: TButton;  
  20.     procedure Button1Click(Sender: TObject);  
  21.     procedure FormDestroy(Sender: TObject);  
  22.     procedure btnSetEventClick(Sender: TObject);  
  23.     procedure btnResetEventClick(Sender: TObject);  
  24.     procedure btnPulseEventClick(Sender: TObject);  
  25.     procedure FormCreate(Sender: TObject);  
  26.   private  
  27.     { Private declarations }  
  28.   public  
  29.     { Public declarations }  
  30.   end;  
  31.    
  32. var  
  33.   Form2: TForm2;  
  34.   hEvent:THandle;  
  35. implementation  
  36.    
  37. uses MyThread;  
  38.    
  39. {$R *.dfm}  
  40.    
  41. procedure TForm2.btnPulseEventClick(Sender: TObject);  
  42. begin  
  43.   PulseEvent(hEvent);  
  44. end;  
  45.    
  46. procedure TForm2.btnResetEventClick(Sender: TObject);  
  47. begin  
  48.   ResetEvent(hEvent);  
  49. end;  
  50.    
  51. procedure TForm2.btnSetEventClick(Sender: TObject);  
  52. begin  
  53.   SetEvent(hEvent);  
  54. end;  
  55.    
  56. procedure TForm2.Button1Click(Sender: TObject);  
  57. begin  
  58.   TMyThread.Create(Label1);  
  59.   TMyThread.Create(Label2);  
  60.   TMyThread.Create(Label3);  
  61.   TMyThread.Create(Label4);  
  62.   TMyThread.Create(Label5);     
  63. end;  
  64.    
  65. procedure TForm2.FormCreate(Sender: TObject);  
  66. begin  
  67.   hEvent:=CreateEvent(nil,True,True,nil);  
  68. end;  
  69.    
  70. procedure TForm2.FormDestroy(Sender: TObject);  
  71. begin  
  72.   CloseHandle(hEvent);  
  73. end;  
  74.    
  75. end.{多线程类}  
  76. unit MyThread;  
  77.    
  78. interface  
  79.    
  80. uses  
  81.   Classes,StdCtrls,SysUtils,Windows;  
  82.    
  83. type  
  84.   TMyThread = class(TThread)  
  85.   private  
  86.     { Private declarations }  
  87.     FLabel:TLabel;  
  88.     str:String;  
  89.     procedure Show;  
  90.   protected  
  91.     procedure Execute; override;  
  92.   public  
  93.     Constructor Create(aLabel:TLabel);  
  94.   end;  
  95.    
  96. implementation  
  97.    
  98. uses Unit2;  
  99.    
  100. { TMyThread }  
  101.    
  102. procedure TMyThread.Show;  
  103. begin  
  104.   FLabel.Caption:=str;  
  105. end;  
  106.    
  107. Constructor TMyThread.Create(aLabel: TLabel);  
  108. begin  
  109.   FLabel:=aLabel;  
  110.   Inherited Create(False);  
  111. end;  
  112.    
  113. procedure TMyThread.Execute;  
  114. var  
  115.   i:Integer;  
  116. begin  
  117.   { Place thread code here }  
  118.   FreeOnTerminate:=True;  
  119.   for i := 0 to 2000 do  
  120.     begin  
  121.     if WaitForSingleObject(hEvent,INFINITE)=WAIT_OBJECT_0 then  
  122.       begin  
  123.        if not Terminated then  
  124.         begin  
  125.           str:=Format(\'线程ID:%.4d,第%.4d个循环。\',[GetCurrentThreadId,i]);  
  126.           Show;  
  127.           //Synchronize(Show);   
  128.         end;  
  129.       end;  
  130.   end;  
  131.    
  132. end;  
  133.    
  134. end.  

 

这里要把WaitForSingleObject放到循环中,这样才可以看到在循环的时候暂停。

 

这里有一个问题,有的时候会出现”Canvas  does not allow drawing”错误。应该是多线程访问VCL的原因,不知道怎么修改代码。加上Lock和UnLock,程序却死掉了。

如果要将Event事件像Mutex那样使用,那么程序改成以下这样:

//创建事件中指定不允许手工暂停

    procedure TForm2.FormCreate(Sender: TObject);  
  1. begin  
  2.   hEvent:=CreateEvent(nil,false,True,nil);  
  3. end;  
  4.    
  5. //多线程的执行过程   
  6. procedure TMyThread.Execute;  
  7. var  
  8.   i:Integer;  
  9. begin  
  10.   { Place thread code here }  
  11.   FreeOnTerminate:=True;  
  12.   if WaitForSingleObject(hEvent,INFINITE)=WAIT_OBJECT_0 then  
  13.   for i := 0 to 2000 do  
  14.     begin  
  15.       if not Terminated then  
  16.         begin  
  17.           str:=Format(\'线程ID:%.4d,第%.4d个循环。\',[GetCurrentThreadId,i]);  
  18.           Show;  
  19.           //Synchronize(Show);   
  20.         end;  
  21.   end;  
  22.   SetEvent(hEvent);  
  23. end;  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
用 matlab 爬取期刊影响因子发布时间:2022-07-18
下一篇:
(原创)matlab符号微分含有未知函数时的导数计算发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap