User talk:Wvanhuffel

Making Delphi VCL component access Thread Safe - an example
The Delphi programming language a RAD tool that contains components for fast program development. Components are reusable code constructs that can be from 3rd party development or be build by the system developer. There are 2 basic types of component - Invisible and Visible.

As a general rule the basis components supplied in the Delphi programming language IDE are not thread safe and it is therefore not appropriate to use them from within a thread based application. For instance, a TMemo component cannot be referenced directly from a HTTPServer objects' methods such as Get, Post or Command Other - if this is done an exception is generated and the program appears to hang.

It is possible to allow VCL components to be accessed from within a thread by using the TRTLCriticalSection object and its associated critical section management functions: InitializeCriticalSection DeleteCriticalSection EnterCriticalSection LeaveCriticalSection In using these there are some specific programming requirements that should be undertaken: 1. Specify the lock object reference to the TRTLCriticalSection object 2. OnCreate of the main form specify the InitializeCriticalSection 3. OnDestroy of the main from clean up with the DeleteCriticalSection 4. Use an independant routine to contain the reference to the VCL component being accessed 4a. When accessing the VCL component EnterCriticalSection and LeaveCriticalSection should be called before and after the component has been used.

The Code
The following is a code based example of the technique described above (abreviated): This code sample is using Delphi 2005 and the Indy 10 (http://www.indyproject.org/) components ... unit definition and uses clause... TForm1 = class(TForm) ...    Memo2: TMemo; IdHTTPServer1: TIdHTTPServer; ... private { Private declarations } FLock: TRTLCriticalSection; public { Public declarations } procedure UpdateMemo2(s: string); end; ... procedure TForm1.UpdateMemo2(s: string); begin EnterCriticalSection(FLock); try memo2.lines.add(s); finally LeaveCriticalSection(FLock); end; end; ... procedure TForm1.FormCreate(Sender: TObject); begin InitializeCriticalSection(FLock); IdHTTPServer1.Active := true; end; procedure TForm1.FormDestroy(Sender: TObject); begin DeleteCriticalSection(FLock); IdHTTPServer1.Active := false; end; ... procedure TForm1.IdHTTPServer1CommandOther(AContext: TIdContext;   const asCommand, asData, asVersion: string); begin UpdateMemo2('incomming data ='+  AContext.Connection.Socket.InputBufferAsString); end; ...