在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
异步编程,是项目中非常有用的而且常用的一种方法,大多以线程实现。 而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(9)))); //Debug output: f1(9) = 81 f2 := function (num: Integer): string begin Result := IntToStr(num * num); end; OutputDebugString(PChar('f2(9) = ' + f2(9))); //Debug output: f2(9) = 81 end;
由此可延伸开来,匿名线程与匿名方法结合,可简单的执行并行操作,举例如下: procedure TfrmMain.btnStartClick(Sender: TObject); begin Edit1.Text := 'start...'; TThread.CreateAnonymousThread( procedure var i: Integer; begin Sleep(3000); for i := 0 to 99999 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) |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论