A few years ago I posted in this mailing list about my implementation of creating thread through a simple method. I'm not sure who copied it into the RTL, but I was checking on it today and it's wrong.
Wrong in the fact that's its just not usable given the copied design. Here is how it should work. procedure TSomeForm.DoWork(Thread: TSimpleThread); begin while not Thread.Terminated do // DoIntensiveWork suppossably returns some text message Thread.Status := DoIntensiveWork; Thread.Status := 'Work done!' end; procedure TSomeForm.DoWorkStatus(Sender: TObject); begin // Safely do something with the thread status text StatusMemo.Lines.Add(Status); end; procedure TSomeForm.IntensiveButtonClick(Sender: TObject); begin // Stop any previous work if FWork <> nil then FWork.Terminate; // Start some work FWork := TSimpleThread.Create(DoWork, DoWorkStatus); end; procedure TSomeForm.FormDestroy(Sender: TObject); begin // Clean up FWork.Free; end; So in a nutshell, you can define work to be done on a thread without the need to define a TThread derived class. Status is optional. Freeing is optional. Here's the problems with the RTL version. A) TThread.ExecuteInThread returns a TThread B) The actual instance returned by ExecuteInThread is TSimpleStatusProcThread C) User has to know to typecast the return D) Type TSimpleStatusProcThread has no accessible methods or properties E) Status cannot be set, terminated cannot be checked, and no synchronization is available If anyone cares to fix this, for reference here is my class declaration. Usage is as simple as, FWork := TSimpleThread.Create(DoWork, DoWorkStatus); with DoWorkStatus being optional. { TThreadExecuteMethod is the method invoked when a TSimpleThread is created } TThreadExecuteMethod = procedure(Thread: TSimpleThread) of object; { TSimpleThread allows objects to create a threading method without defining a new thread class See also <link Overview.Codebot.System.TSimpleThread, TSimpleThread members> } TSimpleThread = class(TThread) private FExecuteMethod: TThreadExecuteMethod; FTempStatus: string; FStatus: string; FOnStatus: TNotifyEvent; procedure DoStatus; procedure SetStatus(const Value: string); protected { Sets FreeOnTerminate to True and executes the method } procedure Execute; override; public { Create immediately starts ExecuteMethod on a new thread } constructor Create(ExecuteMethod: TThreadExecuteMethod; OnStatus: TNotifyEvent = nil; OnTerminate: TNotifyEvent = nil); { Synchronize can be used by ExecuteMethod to invoke a method on the main thread } procedure Synchronize(Method: TThreadMethod); { You should only set status inside ExecuteMethod } property Status: string read FStatus write SetStatus; { Terminated is set to True after the Terminate method is called } property Terminated; end;
_______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal