Delphi异步编程:匿名线程与匿名方法
异步编程,是项目中非常有用的而且常用的一种方法,大多以线程实现。
而Delphi传统方法使用线程略为烦琐,好在其后续版本中,提供一些方法,简化一些操作。
几个概念:
匿名线程:TAnonymousThread,Delphi XE始支持。
匿名方法:reference to procedure|function,Delphi 2009 始支持。
匿名线程
其实只是创建一个线程,传入一匿名方法并执行,实现倒也简单,我就移其入Dephi 2009中。其实义如下:
TAnonymousThread = class(TThread)
private
FProc: TProc;
protected
procedure Execute; override;
public
constructor Create(const AProc: TProc);
end;
{ TAnonymousThread } constructor TAnonymousThread.Create(const AProc: TProc);
begin
inherited Create(True);
FreeOnTerminate := True;
FProc := AProc;
end; procedure TAnonymousThread.Execute;
begin
FProc();
end;
这样,使用简单的多线程,就不必再继承TThread类创建自己线程去工作了。其参数TProc,即为一匿名方法。
而在TThread类中,定义一类方法直接创建,其方法为:
// CreateAnonymousThread will create an instance of an internally derived TThread that simply will call the
// anonymous method of type TProc. This thread is created as suspended, so you should call the Start method
// to make the thread run. The thread is also marked as FreeOnTerminate, so you should not touch the returned
// instance after calling Start as it could have run and is then freed before another external calls or
// operations on the instance are attempted.
class function CreateAnonymousThread(const ThreadProc: TProc): TThread; static;
class function TThread.CreateAnonymousThread(const ThreadProc: TProc): TThread;
begin
Result := TAnonymousThread.Create(ThreadProc);
end;
由此可见,一行代码即可实现简单的线程操作。
匿名方法
自定义匿名方法,正式语法为:
type
TFun = reference to function(const num: Integer): Integer;
procedure也是一样。但在SysUtils单元中,已内置一些预定义类型并且支持泛型,可直接拿来用,如下所示:
// Generic Anonymous method declarations
type
TProc = reference to procedure;
TProc<T> = reference to procedure (Arg1: T);
TProc<T1,T2> = reference to procedure (Arg1: T1; Arg2: T2);
TProc<T1,T2,T3> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3);
TProc<T1,T2,T3,T4> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4); TFunc<TResult> = reference to function: TResult;
TFunc<T,TResult> = reference to function (Arg1: T): TResult;
TFunc<T1,T2,TResult> = reference to function (Arg1: T1; Arg2: T2): TResult;
TFunc<T1,T2,T3,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult;
TFunc<T1,T2,T3,T4,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult; TPredicate<T> = reference to function (Arg1: T): Boolean;
我是喜欢懒省事的,有已有的即不再自写,上面诸多类型,已能应对大多数使用场景了。
需要注意的是TFunc使用方法,因为它有返回值。比如TFunc<Integer, Interger>就与TFun实现原理一样。
可验证如下代码:
procedure TfrmMain.FormCreate(Sender: TObject);
var
f1: TFun;
f2: TFunc<Integer, string>;
begin
f1 := function (const num: Integer): Integer
begin
Result := num * num;
end;
OutputDebugString(PChar('f1(9) = ' + IntToStr(f1()))); //Debug output: f1(9) = 81 f2 := function (num: Integer): string
begin
Result := IntToStr(num * num);
end;
OutputDebugString(PChar('f2(9) = ' + f2())); //Debug output: f2(9) = 81
end;
由此可延伸开来,匿名线程与匿名方法结合,可简单的执行并行操作,举例如下:
procedure TfrmMain.btnStartClick(Sender: TObject);
begin
Edit1.Text := 'start...';
TThread.CreateAnonymousThread(
procedure
var
i: Integer;
begin
Sleep();
for i := to do
TThread.Synchronize(nil,
procedure
begin
Edit1.Text := IntToStr(i);
end
);
Edit1.Text := 'end.'; //此处亦要同步,懒省事没整Synchornize
end
).Start;
end;
创建一匿名线程,传以匿名方法,并同步主线程显示,工作正常。相比c#之{}来说,begin..end的确看起业不像话。
多省事,是不是?
参考资料:
Delphi 2009 中的匿名方法(reference to)
Delphi异步编程:匿名线程与匿名方法的更多相关文章
- C#:异步编程和线程的使用(.NET 4.5 )
摘自:http://www.codeproject.com/Articles/996857/Asynchronous-programming-and-Threading-in-Csharp-N(葡萄城 ...
- 异步编程和线程的使用(.NET 4.5 )
C#:异步编程和线程的使用(.NET 4.5 ) 异步编程和线程处理是并发或并行编程非常重要的功能特征.为了实现异步编程,可使用线程也可以不用.将异步与线程同时讲,将有助于我们更好的理解它们的特征 ...
- C#:异步编程和线程的使用(.NET 4.5 ),异步方法改为同步执行
摘自:http://www.codeproject.com/Articles/996857/Asynchronous-programming-and-Threading-in-Csharp-N(葡萄城 ...
- ES6 --- JS异步编程的几种解决方法及其优缺点
导言: 我们都知道 JS 是单线程的,这也正是异步编程对于 JS 很重要的原因,因为它无法忍受耗时太长的操作.正因如此有一系列的实现异步的方法. 方法一 setTimeout 常用于:定时器,动画 ...
- C#5.0 异步编程 Async和Await--异步方法的规范和注意事项
要些异步方法要注意一下几点: 异步方法的返回值有三种: 1.没有任何返回值的void 2.返回一个Task任务的Task,可以获得该异步方法的执行状态 3.返回Task<T> 可以获得异步 ...
- 廖雪峰Java11多线程编程-2线程同步-2synchronized方法
1.Java使用synchronized对一个方法进行加锁 class Counter{ int count = 0; public synchronized void add(int n){ cou ...
- JUC 并发编程--08,线程池,三大方法,七大参数,4种拒绝策略,代码演示
三大方法: //线程池核心线程数为n, 最大线程数为 n ExecutorService fixedThreadPool = Executors.newFixedThreadPool(n); 源码: ...
- C#异步编程の----Threadpool( 线程池)
简介: 一个托管线程的创建需要数千个CPU周期,并且当发生线程切换时也会带来明显的开销.考虑线程的重用,避免不断重复创建新的线程是提高系统效率的一种方式. 线程池是一种提供效率的方式,它创建好一些线程 ...
- 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法
什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...
随机推荐
- 【JEECG技术文档】Online唯一校验使用说明
1.功能介绍 配置了唯一校验的字段,在录入和编辑页面中,动态查询用户输入值是否存在校验. 要使用online唯一校验功能必须先在online表单开发中配置唯一字段的校验方式为唯一校验. 2.配置唯一校 ...
- linux集群时间同步搭建
http://xstarcd.github.io/wiki/sysadmin/ntpd.html http://www.voidcn.com/blog/xuxudede1989/article/p-4 ...
- poi excel
使用apache的poi包可以对excel进行操作读取和写入. 因excel分为xls的2003版和xlsx的2007版,poi在创建workbook时使用不同的类创建,因此需要注意区分xls. Wo ...
- 创建模式--单例模式Singleton(JAVA)
创建模式之单例模式 在面试时经常会有人问单例模式,单例模式是在整个系统运行中仅且仅有一个实例,在被调用.我们熟知的Calendar就是这种, Calendar.newIns ...
- Delphi TMemoryStream写入到字符串和字符串写入到流
一.TMemoryStream数据写入到字符串里 var lvStream:TMemoryStream; s:AnsiString; p: PAnsiChar; begin lvStream:= TM ...
- 尚硅谷redis学习4-数据类型
redis的数据类型包括String,Hash(类似于JAVA里的map),List,Set,Zset(sorted Set) String(字符串) string是redis最基本的类型,你可以理解 ...
- Win7下npm命令Error: ENOENT问题解决
Win7下在执行npm命令,比如npm list时出现下面错误:
- openvpn 批量生成用户脚本
#/bin/bash for user in "$@" do echo "新增用户:$user" if [ -d "/etc/openvpn/clie ...
- 关于openwrt使用web升级提示固件版本不对的处理方法
参考资料:https://blog.csdn.net/caoshunxin01/article/details/79355602 当openwrt使用web升级提示固件版本不对: The upload ...
- ArcGIS自定义工具箱-自增字段(可以设置初始值和步长)
ArcGIS自定义工具箱-自增字段(可以设置初始值和步长) 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:字段值初始值为设定值(默认为0),每次增加一个步长( ...