Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a simple example how you can do it...</p> <pre><code>const WM_MY_RESULT = WM_USER + $1; type TMyThread = class(TThread) private FKilled: Boolean; FListLock: TRTLCriticalSection; FList: TList; FJobAdded: TEvent; protected procedure Execute; override; procedure DoJob(AJob: Integer); public constructor Create(CreateSuspended: Boolean); destructor Destroy; override; procedure Kill; procedure PushJob(AJob: Integer); function JobCount: Integer; function GetJob: Integer; end; TThreadingForm = class(TForm) lstResults: TListBox; se: TSpinEdit; btn: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btnClick(Sender: TObject); private FThread: TMyThread; procedure OnMyResultMessage(var Msg: TMessage); message WM_MY_RESULT; public { Public declarations } end; var ThreadingForm: TThreadingForm; implementation {$R *.dfm} { TMyThread } constructor TMyThread.Create(CreateSuspended: Boolean); begin FKilled := False; InitializeCriticalSection(FListLock); FList := TList.Create; FJobAdded := TEvent.Create(nil, True, False, 'job.added'); inherited; end; destructor TMyThread.Destroy; begin FList.Free; FJobAdded.Free; DeleteCriticalSection(FListLock); inherited; end; procedure TMyThread.DoJob(AJob: Integer); var res: Integer; begin res := AJob * AJob * AJob * AJob * AJob * AJob; Sleep(1000); // so it would take some time PostMessage(ThreadingForm.Handle, WM_MY_RESULT, res, 0); end; procedure TMyThread.Execute; begin inherited; while not FKilled or not Self.Terminated do begin EnterCriticalSection(FListLock); if JobCount &gt; 0 then begin LeaveCriticalSection(FListLock); DoJob(GetJob) end else begin FJobAdded.ResetEvent; LeaveCriticalSection(FListLock); FJobAdded.WaitFor(10000); end; end; end; function TMyThread.GetJob: Integer; begin EnterCriticalSection(FListLock); try Result := Integer(FList[0]); FList.Delete(0); finally LeaveCriticalSection(FListLock); end; end; function TMyThread.JobCount: Integer; begin EnterCriticalSection(FListLock); Result := FList.Count; LeaveCriticalSection(FListLock); end; procedure TMyThread.Kill; begin FKilled := True; FJobAdded.SetEvent; Terminate; end; procedure TMyThread.PushJob(AJob: Integer); begin EnterCriticalSection(FListLock); try FList.Add(Pointer(AJob)); FJobAdded.SetEvent; finally LeaveCriticalSection(FListLock); end; end; { TThreadingForm } procedure TThreadingForm.OnMyResultMessage(var Msg: TMessage); begin lstResults.Items.Add(IntToStr(Msg.WParam)); end; procedure TThreadingForm.FormCreate(Sender: TObject); begin FThread := TMyThread.Create(False); end; procedure TThreadingForm.FormDestroy(Sender: TObject); begin FThread.Kill; FThread.WaitFor; FThread.Free; end; procedure TThreadingForm.btnClick(Sender: TObject); begin FThread.PushJob(se.Value); end; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload