qworker 实例

unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, qrbtree, qworker, SyncObjs, ExtCtrls, dateutils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button4: TButton;
    Label1: TLabel;
    Timer1: TTimer;
    Label2: TLabel;
    Button3: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Button10: TButton;
    Button11: TButton;
    Button12: TButton;
    Button13: TButton;
    Button14: TButton;
    Button15: TButton;
    Label3: TLabel;
    Button16: TButton;
    Button17: TButton;
    Label4: TLabel;
    Button18: TButton;
    Button19: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure Button12Click(Sender: TObject);
    procedure Button13Click(Sender: TObject);
    procedure Button14Click(Sender: TObject);
    procedure Button15Click(Sender: TObject);
    procedure Button16Click(Sender: TObject);
    procedure Button17Click(Sender: TObject);
    procedure Button18Click(Sender: TObject);
    procedure Button19Click(Sender: TObject);
  private
    { Private declarations }
    FSignalId: Integer;
    procedure DoJobProc(AJob: PQJob);
    procedure DoPostJobDone(AJob: PQJob);
    procedure DoMainThreadWork(AJob: PQJob);
    procedure DoPostJobMsg(var AMsg: TMessage); message WM_APP;
    procedure SignalWaitProc(AJob: PQJob);
    procedure DoSignalJobMsg(var AMsg: TMessage); message WM_APP + 1;
    procedure DoTimerProc(AJob: PQJob);
    procedure DoTimerJobMsg(var AMsg: TMessage); message WM_APP + 2;
    procedure DoLongtimeWork(AJob: PQJob);
    procedure DoLongworkDone(AJob: PQJob);
    procedure DoAtTimeJob1(AJob: PQJob);
    procedure DoAtTimeJob2(AJob: PQJob);
    procedure DoDelayJob(AJob: PQJob);
    procedure DoCancelJob(AJob: PQJob);
    procedure DoNullJob(AJob: PQJob);
    procedure DoCOMJob(AJob: PQJob);
    procedure DoRandDelay(AJob: PQJob);
    procedure SelfTerminateJob(AJob: PQJob);
  public
    { Public declarations }
  end;

TAutoFreeTestObject = class
  public
    constructor Create; overload;
    destructor Destroy; override;
  end;

PAutoFreeRecord = ^TAutoFreeRecord;

TAutoFreeRecord = record
    Id: Integer;
  end;

var
  Form1: TForm1;

implementation

uses
  qstring, comobj;
{$R *.dfm}

procedure TForm1.SelfTerminateJob(AJob: PQJob);
begin
  Label4.Caption := ‘自结束作业已运行 ‘ + IntToStr(AJob.Runs) + ‘次‘;
  if AJob.Runs = 3 then
  begin
    AJob.IsTerminated := True;
    Label4.Caption := ‘自结束作业已结束.‘;
  end;
end;

procedure TForm1.SignalWaitProc(AJob: PQJob);
begin
  PostMessage(Handle, WM_APP + 1, AJob.Runs, 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Workers.Signal(FSignalId);
end;

procedure TForm1.Button10Click(Sender: TObject);
var
  ATime: TDateTime;
begin
  ATime := Now;
  ATime := IncSecond(ATime, 10);
  Workers.at(DoAtTimeJob2, ATime, QWorker.Q1Hour, nil, True);
  ShowMessage(‘这个任务将在‘ + FormatDateTime(‘hh:nn:ss.zzz‘, ATime) + ‘时第一次启动,以后每隔1小时定时启动一次。‘);
end;

procedure TForm1.Button11Click(Sender: TObject);
begin
  Workers.Post(DoCancelJob, Pointer(1));
//直接取消简单作业队列中的作业,正常情况下是没来的及执行
  Workers.Clear(DoCancelJob, Pointer(1));
  Workers.Post(DoCancelJob, Pointer(2));
//作业已经进行了,取消操作会等待作业完成
  Sleep(100);
  Workers.Clear(DoCancelJob, Pointer(2));
//重复作业
  Workers.Post(DoCancelJob, 1000, Pointer(3));
//直接取消重复作业队列中的作业
  Workers.Clear(DoCancelJob, Pointer(3));
//重复作业
  Workers.Post(DoCancelJob, 1000, Pointer(4));
  Sleep(200);
//直接取消重复作业队列中的作业
  Workers.Clear(DoCancelJob, Pointer(4));
//信号作业队列
  Workers.Wait(DoCancelJob, FSignalId, Pointer(5));
  Workers.Clear(DoCancelJob, Pointer(5));
end;

procedure TForm1.Button12Click(Sender: TObject);
var
  AData: PAutoFreeRecord;
begin
  Workers.Post(DoNullJob, TAutoFreeTestObject.Create, false, jdfFreeAsObject);
  New(AData);
  Workers.Delay(DoNullJob, 1000, AData, false, jdfFreeAsRecord);
end;

procedure TForm1.Button13Click(Sender: TObject);
begin
  Workers.Post(DoCOMJob, nil);
end;

procedure TForm1.Button14Click(Sender: TObject);
begin
  Workers.Signal(‘MySignal.Start‘);
  Workers.Signal(‘MySignal.Start‘);
  Workers.Post(DoNullJob, nil);
  Workers.Clear(‘MySignal.Start‘);
end;

procedure TForm1.Button15Click(Sender: TObject);
begin
  Workers.Delay(DoRandDelay, Q1Second, nil);
end;

procedure DoGlobalJob(AJob: PQJob);
begin
  ShowMessage(‘全局函数作业已调用。‘);
end;

procedure TForm1.Button16Click(Sender: TObject);
begin
  Workers.Post(MakeJobProc(DoGlobalJob), nil, True);
end;

procedure TForm1.Button17Click(Sender: TObject);
begin
  Workers.Post(SelfTerminateJob, 10000, nil, true);
end;

procedure TForm1.Button18Click(Sender: TObject);
var
  AId: Integer;
  T: Cardinal;
begin
  AId := Workers.RegisterSignal(‘Signal.SelfKill‘);
  Workers.Wait(SelfTerminateJob, AId, nil, True);
  Workers.Signal(AId);
  T := GetTickCount;
  while GetTickCount - T < 500 do
    Application.ProcessMessages;
  Workers.Signal(AId);
  T := GetTickCount;
  while GetTickCount - T < 500 do
    Application.ProcessMessages;
  Workers.Signal(AId);
  T := GetTickCount;
  while GetTickCount - T < 500 do
    Application.ProcessMessages;
  Workers.Signal(AId);
end;

procedure TForm1.Button19Click(Sender: TObject);
var
  AGroup: TQJobGroup;
  AMsg: string;
begin
  AGroup := TQJobGroup.Create(True);
  if AGroup.WaitFor() <> wrSignaled then
    AMsg := ‘WaitFor空作业列表失败‘;
  AGroup.Prepare;
  AGroup.Add(DoNullJob, nil, false);
  AGroup.Add(DoNullJob, nil, false);
  AGroup.Add(DoNullJob, nil, false);
  AGroup.Run;
  if AGroup.WaitFor() <> wrSignaled then
    AMsg := ‘WaitFor多个作业失败‘;
  FreeObject(AGroup);
  if Length(AMsg) > 0 then
    ShowMessage(AMsg)
  else
    ShowMessage(‘分组作业执行成功完成。‘);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1Timer(Sender);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Workers.Post(DoPostJobDone, nil);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ShowMessage(IntToStr(GetTimeStamp));
end;

procedure TForm1.Button4Click(Sender: TObject);
const
  ACount: Integer = 10000000;
var
  I, ARuns: Integer;
  T1: Int64;
  ANeedRuns: Int64;
begin
  ARuns := 0;
//Workers.MaxWorkers:=500;
  ANeedRuns := ACount;
  T1 := GetTimeStamp;
  for I := 0 to ACount - 1 do
  begin
    assert(Workers.Post(DoJobProc, @ARuns), ‘Post failure‘);
  end;
  while (ARuns < ANeedRuns) do
  {$IFDEF UNICODE}
    TThread.Yield;
  {$ELSE}
  SwitchToThread;
  {$ENDIF}
  T1 := GetTimeStamp - T1;
  ShowMessage(‘Time Used=‘ + IntToStr(T1) + ‘,Runs=‘ + IntToStr(ARuns) + ‘,Speed=‘ + IntToStr(Int64(ARuns) * 10000 div T1));
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  Workers.Post(DoMainThreadWork, nil, True);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  Workers.Signal(‘MySignal.Start‘);
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  if not Workers.LongtimeJob(DoLongtimeWork, nil) then
    ShowMessage(‘长时间作业投寄失败‘);
end;

procedure TForm1.Button8Click(Sender: TObject);
begin
  ShowMessage(‘这个任务将在5秒后第一次启动,以后每隔1小时定时启动一次。‘);
  Workers.at(DoAtTimeJob1, 5 * QWorker.Q1Second, QWorker.Q1Hour, nil, True)
end;

procedure TForm1.Button9Click(Sender: TObject);
begin
  Workers.Delay(DoDelayJob, 5 * QWorker.Q1Second, nil, True)
end;

procedure TForm1.DoAtTimeJob1(AJob: PQJob);
begin
  ShowMessage(‘定时5秒后执行的任务已经执行了‘ + IntToStr(AJob.Runs + 1) + ‘次,1小时后执行下一次‘);
end;

procedure TForm1.DoAtTimeJob2(AJob: PQJob);
begin
  ShowMessage(‘定时任务已在‘ + FormatDateTime(‘yyyy-mm-dd hh:nn:ss.zzz‘, Now) + ‘开始第‘ + IntToStr(AJob.Runs + 1) + ‘次执行,1小时后执行下一次‘#13#10 + ‘入队时间:‘ + IntToStr(AJob.PushTime) + #13#10 + ‘出队时间:‘ + IntToStr(AJob.PopTime));
end;

procedure TForm1.DoCancelJob(AJob: PQJob);
begin
  OutputDebugString(PWideChar(‘DoCancelJob(‘ + IntToHex(IntPtr(AJob), 8) + ‘)-‘ + IntToStr(Integer(AJob.Data)) + ‘ Started‘));
  Sleep(5000);
  OutputDebugString(PWideChar(‘DoCancelJob(‘ + IntToHex(IntPtr(AJob), 8) + ‘)-‘ + IntToStr(Integer(AJob.Data)) + ‘ Finished‘));
end;

procedure TForm1.DoCOMJob(AJob: PQJob);
var
  ADispatch: IDispatch;
begin
  AJob.Worker.ComNeeded();
  try
    ADispatch := CreateOleObject(‘ADODB.Recordset‘);
  except
  end;
end;

procedure TForm1.DoDelayJob(AJob: PQJob);
begin
  ShowMessage(‘延迟的任务已经执行完成了。‘#13#10 + ‘入队时间:‘ + IntToStr(AJob.PushTime) + #13#10 + ‘出队时间:‘ + IntToStr(AJob.PopTime));
end;

procedure TForm1.DoJobProc(AJob: PQJob);
begin
  AtomicIncrement(PInteger(AJob.Data)^);
end;

procedure TForm1.DoLongtimeWork(AJob: PQJob);
begin
  while not AJob.IsTerminated do
  begin
    Sleep(1000);
    if AJob.EscapedTime > 50000 then//5s后结束任务,注意计时单位为0.1ms
      AJob.IsTerminated := True;
  end;
  if not Workers.Terminating then//如果未结束,则触发一个通知能前台,这样方便前台做一些进一步处理
    Workers.Signal(‘Longwork.Done‘);
end;

procedure TForm1.DoLongworkDone(AJob: PQJob);
begin
  ShowMessage(‘长时间作业已经完成‘);
end;

procedure TForm1.DoMainThreadWork(AJob: PQJob);
begin
  ShowMessage(‘这是在主线程中触发的异步作业。‘);
end;

procedure TForm1.DoNullJob(AJob: PQJob);
begin
  OutputDebugString(‘Null Job Executed‘);
end;

procedure TForm1.DoPostJobDone(AJob: PQJob);
begin
  PostMessage(Handle, WM_APP, AJob.PopTime - AJob.PushTime, 0);
end;

procedure TForm1.DoPostJobMsg(var AMsg: TMessage);
begin
  ShowMessage(Format(‘作业投寄到执行用时 %g ms‘, [AMsg.WParam / 10]));
end;

procedure TForm1.DoRandDelay(AJob: PQJob);
begin
  Label3.Caption := ‘随机作业末次延迟 ‘ + IntToStr((AJob.PopTime - AJob.PushTime) div 10) + ‘ms‘;
  Workers.Delay(AJob.WorkerProc, qworker.Q1Second + random(qworker.Q1Second), AJob.Data, True);
end;

procedure TForm1.DoSignalJobMsg(var AMsg: TMessage);
begin
  Label2.Caption := Format(‘信号MySignal.Start已触发 %d次‘, [AMsg.WParam]);
end;

procedure TForm1.DoTimerJobMsg(var AMsg: TMessage);
begin
  Label1.Caption := ‘定时任务已执行‘ + IntToStr(AMsg.WParam) + ‘次‘;
end;

procedure TForm1.DoTimerProc(AJob: PQJob);
begin
  PostMessage(Handle, WM_APP + 2, AJob.Runs, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutDown := True;
//注册一个信号触发函数,以便在触发时执行
  FSignalId := Workers.RegisterSignal(‘MySignal.Start‘);
  Workers.Wait(SignalWaitProc, FSignalId, nil);
//使用名称来触发的信号
  Workers.Wait(DoLongworkDone, Workers.RegisterSignal(‘Longwork.Done‘), nil, true);
//注册一个定时执行任务信号,每0.1秒触发一次
  Workers.Post(DoTimerProc, 1000, nil);
  Caption := ‘QWorker Demo (CPU:‘ + IntToStr(GetCpuCount) + ‘)‘;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Workers.Clear(Self);
end;

{ TAutoFreeTestObject }

constructor TAutoFreeTestObject.Create;
begin
  OutputDebugString(‘TAutoFreeTestObject.Create‘);
end;

destructor TAutoFreeTestObject.Destroy;
begin
  OutputDebugString(‘TAutoFreeTestObject.Free‘);
  inherited;
end;

end.

时间: 2024-08-29 06:56:48

qworker 实例的相关文章

[DIOCP3/MyBean/QDAC开源项目] DataModule-DB例子基于MyBean的插件实例&lt;三层数据库方案&gt;

[说明] 这个例子答应大家很久了,一直没有时间弄,现在正式结合MyBean插件可以很方便的在客户端共享操作连接,执行数据库的各项工作,屏蔽了底层的通信解码器编码等工作,直接传递Variant,给了开发者足够的领活和自由. [服务端使用技术] diocp3:担当底层的通信任务. qworker/iocpTask:担当业务逻辑的处理工作,diocp3接受数据解码后用qworker/iocpTask将数据包投递出来,这样不用占用通信线程. qmsgpack:负责将传递的将variant数据打包到流,从

solr分布式索引【实战一、分片配置读取:工具类configUtil.java,读取配置代码片段,配置实例】

1 private static Properties prop = new Properties(); 2 3 private static String confFilePath = "conf" + File.separator + "config.properties";// 配置文件目录 4 static { 5 // 加载properties 6 InputStream is = null; 7 InputStreamReader isr = null;

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

【Kettle】4、SQL SERVER到SQL SERVER数据转换抽取实例

1.系统版本信息 System:Windows旗舰版 Service Pack1 Kettle版本:6.1.0.1-196 JDK版本:1.8.0_72 2.连接数据库 本次实例连接数据库时使用全局变量. 2.1 创建新转换:spoon启动后,点击Ctrl+N创建新转换 2.2 在新转换界面中,右键点击DB连接,系统会弹出[数据库连接]界面. windows系统环境下,可用${}获取变量的内容. 说明: 连接名称:配置数据源使用名称.(必填) 主机名称:数据库主机IP地址,此处演示使用本地IP(

ORACLE11g R2【RAC+ASM→单实例FS】

ORACLE11g R2[RAC+ASM→单实例FS] 11g R2 RAC+ASMà单实例FS的DG,建议禁用OMF. 本演示案例所用环境:   primary standby OS Hostname node1,node2 std OS Version RHEL6.5 RHEL6.5 DB Version 11.2.0.4 11.2.0.4 db_name stephen stephen db_unique_name stephen standby service_names stephen

Laravel 5.4 中的异常处理器和HTTP异常处理实例教程

错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器中(出于安全考虑),这个时候我们仍然要捕获异常,只不过不是显示到浏览器中,而是记录到日志中,方便日后排查问题. 百牛信息技术bainiu.ltd整理发布于博客园 Laravel当然支持PHP原生的错误和异常处理,但是在此基础上进行了一些封装处理,从而更方便在不同开发环境切换以及对错误和异常的处理.

Hibernate简述及入门实例

一.Hibernate简述 总的概括,Hibernate是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性).hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库. 二.使用myeclipse创建hibernate实例两种方法(以hibernate3.5.2及mysql为例) a)手动编写hibernate.cfg.xml及*.hb

linux下mysql多实例安装(转)

转自:http://www.cnblogs.com/xuchenliang/p/6843990.html 1.MySQL多实例介绍 1.1.什么是MySQL多实例 MySQL多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过不同的socket监听不同的服务端口来提供各自的服务:: 1.2.MySQL多实例的特点有以下几点 1:有效利用服务器资源,当单个服务器资源有剩余时,可以充分利用剩余的资源提供更多的服务. 2:节约服务器资源 3:资源互相

微信小程序实例教程(一)

序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小程序」开发指南) 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点击头像,可以在新开的页面中查看当前小程序的启动日志. 1. 获取微信小程序的 AppID 首先,我们需要拥有一个帐号,如果你能看到该文档,我们应当已经邀请并为你创建好一个帐号.注意不可直接使用服务号或订阅号的 AppID. 利用提供的帐号,登录https