Author: David Clegg
Reading Anders Ohlsson’s latest blog post about using iOS APIs we don’t wrap reminded me of another couple of helper classes that I created, and which ship with the RAD Studio XE4 samples.
The first of these is the TAnonymousThread
TAnonymousThread= class(TThread)
public
constructor Create(AThreadFunc: TFunc; AOnFinishedProc: TProc ;
AOnErrorProc: TProc; AStartSuspended: Boolean = False;
AFreeOnTerminate: Boolean = True);
end;
As you can see, the interface is pretty straightforward. It takes a series of procedure and function pointers to allow you to specify a function to be run in the thread, a callback procedure which will be run in the main thread so you can process the result, and a callback procedure which will run in the main thread if an exception occurs during thread processing. By default it will not start the thread suspended, and will free the thread on termination (for platforms that don’t have ARC implementations).
Here is an example of using this class:-
var
lThread: TAnonymousThread;
begin
lThread := TAnonymousThread.Create(
function: Boolean
begin
//Runs in separate thread
Result := SomeLongRunningMethodReturningADataSet;
end,
procedure(AResult: TDataSet)
begin
//Runs in main thread
SomeMethodToProcessDataInMainThread(AResult);
end,
procedure(AException: Exception)
begin
//Runs in main thread
ShowMessage(AException.Message);
end);
end;
The second class is the TAsyncProgress
TAsyncProgress= class
public
class procedure Execute(AFunc: TFunc; AOnFinished: TProc ;
AOnError: TProc);
end;
As you can see, it has a similar interface to TAnonymousThread
Here is an example of using this class:-
TAsyncProgress.Execute(
function: TDataSet;
begin
//Runs in separate thread
Result := SomeMethodReturningADataSet;
end,
procedure(AResult: TDataSet)
begin
//Runs in main thread
SomeMethodToProcessData(AResult);
end,
procedure(AException: Exception)
begin
//Runs in main thread
ShowMessage(AException.Message);
end);
If you look at the implementation of TAsyncProgress
IPleaseWaitService = interface
procedure StartWait;
procedure StopWait;
end;
I have created an implementation of this interface for iOS in iOS.Services.pas, and for OSX in Mac.Services.pas. The iOS implementation uses the technique that Anders blogged about to show the network activity indicator in the iOS status bar, but it also uses the UIActivityIndicatorView class to show a spinning progress indicator in the centre of your application view. Similarly the OSX implementation uses the NSProgressIndicator class to show a spinning progress indicator in the center of your main OSX application view.
To register an implementation for a given platform, simply add the relevant *.Services.pas file to your project.
In addition to leveraging the IPleaseWaitService interface via the TAsyncProgress
//Returns an instance of the IPleaseWaitService registered for the current platform
function PleaseWaitService: IPleaseWaitService;
//Runs the specified procedure (unthreaded), using the IPleaseWaitService interface to
//indicate execution progress.
procedure ProgressProc(AProc: TProc);
//Wraps a call to IPleaseWaitService.StartWait, if the service has been registered
procedure StartWait;
//Wraps a call to IPleaseWaitService.StopWait, if the service has been registered
procedure StopWait;
There are sample applications for iOS showing how to consume the TAnonymousThread
Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Free Delphi Community Edition Free C++Builder Community Edition







