dkounal 3 Posted November 1, 2020 (edited) I need to run a piece of code in TTask threads using a thread pool, that runs in every platform and get the results in the main UI thread in a thread safe message object without checking with a timer. Inspired by a post from Remy Lebeau in the Lazarus forum I wrote the following. Comments, suggestions, errors in the code welcome. interface type TTaskdata < T >= class type mydataP = ^T; mytaskproctyp =procedure(a: mydataP) of object; private Data: T; ProcessData: mytaskproctyp; procedure DoProcess; public procedure queue(datatyp: T; taskproc: mytaskproctyp); end; implementation procedure TTaskdata<T>.queue(datatyp: T; taskproc: mytaskproctyp); begin Data := datatyp; ProcessData := taskproc; TThread.queue(nil, DoProcess); end; procedure TTaskdata<T>.DoProcess; begin ProcessData(@Data); end; In an other/main Tform Unit type Dsoup = record nam: string; i: integer; end; // a sample record for send and receiving data to Ttask routine ReturnProc = procedure(mypointer: Ttaskdata<Dsoup>.mydataP) of object; var FCustomPool: TThreadPool; // the theadpool to be used for reusing threads, it should initialiazed in Tform's constructor procedure TForm1.Button1Click(Sender: TObject); // the initial route that will prepare data for Ttask and run it var soup: Dsoup; begin { set in Dsoup all data to send in TTask routine } TTask.Run(dowork(soup, getresults), FCustomPool); end; function TForm1.dowork(const a: Dsoup; p: ReturnProc): tproc; begin Result := // anonymous function to run by Ttask procedure var ff: Ttaskdata<Dsoup>; begin ff := Ttaskdata<Dsoup>.create; try { do all the task job here } ff.queue(a, p); // add result data to be sent with Thread.queue except ff.free; end; end; end; procedure TForm1.getresults(p: Ttaskdata<Dsoup>.mydataP); begin { here come the results from TTask in the main UI thread } end; Edited November 2, 2020 by dkounal better presentation of code Share this post Link to post
Anders Melander 1782 Posted November 1, 2020 53 minutes ago, dkounal said: Comments, suggestions, errors in the code welcome. Call me old fashioned but the way you've formatted your code makes it close to unreadable to me. 1 Share this post Link to post
dkounal 3 Posted November 1, 2020 10 minutes ago, Anders Melander said: Call me old fashioned but the way you've formatted your code makes it close to unreadable to me. Is it better now? Share this post Link to post
Marat1961 17 Posted November 2, 2020 Borland / CodeGear / Embarcadero / Jedi coding standard. You can see for example how the formatting of System.Classes Share this post Link to post
dkounal 3 Posted November 2, 2020 1 hour ago, Marat1961 said: Borland / CodeGear / Embarcadero / Jedi coding standard. You can see for example how the formatting of System.Classes I apologize. Formated using Delphi's IDE "format source" procedure Share this post Link to post
Marat1961 17 Posted November 2, 2020 (edited) You just need to configure the auto format according to the formatting standard. This format is usually the default. If you think a little, then the following conclusion follows from here: Delphi has only one correct coding standard, and all the others are wrong. When you invite other people to see the code, don't surprise them with your absolutely amazing and most perfect style of code formatting. Edited November 2, 2020 by Marat1961 Share this post Link to post
dkounal 3 Posted November 2, 2020 7 minutes ago, Marat1961 said: You just need to configure the auto format according to the formatting standard. This format is usually the default. If you think a little, then the following conclusion follows from here: Delphi has only one correct coding standard, and all the others are wrong. Delphi IDE 10.4.1 -> Tools -> Options -> Language ->Formatter ->select profile "Formater Default config" -> Apply. The code remains the same after Right Click->Format Source Am I missing something? Thank you in advance for your help Share this post Link to post
Marat1961 17 Posted November 2, 2020 18 hours ago, dkounal said: type TTaskdata<T>= class type mydataP = ^T; mytaskproctyp = procedure(a: mydataP) of object; This code was definitely not passed through the autoformat. You still don't know what the Soviet norm - control is! Share this post Link to post
Marat1961 17 Posted November 2, 2020 It was first done well in this book, Hoare, C. A. R. Communicating sequential processes I have a book "Patterns in Java. A Catalog of Reusable Design Patterns Illustrated with UML | Grand Mark". This book describes the Producer-Consumer pattern, in my opinion this is your case. There are code examples for the queue. 1 Share this post Link to post
dkounal 3 Posted November 2, 2020 13 minutes ago, Marat1961 said: This code was definitely not passed through the autoformat. You still don't know what the Soviet norm - control is! You are correct. This was my only modification as it was reformatted completly unreadable. I give up. Please tell me what to do Share this post Link to post
Marat1961 17 Posted November 2, 2020 (edited) I would use the MCV pattern. The user interface must be subscribed to change the data model. Receiver and consumer must be processes. When the model changes, notify the user interface about the need to update the presentation. Supplier => Consumer => Model MainForm.Refresh; The timer, by the way, is useful in case of a group of changes. So that there is no fuss under the client, it is useful not to draw everything at once, but with some delay of at least 0.2 - 0.5 seconds. procedure TMainForm.RefreshTimerTimer(Sender: TObject); begin RefreshTimer.Enabled: = False; Refresh; end; procedure TMainForm.ModelChanged(Sender: TObject); begin RefreshTimer.Rearm; end; Edited November 2, 2020 by Marat1961 Share this post Link to post
TigerLilly 16 Posted November 4, 2020 Maybe this can help you: https://github.com/spinettaro/delphi-event-bus 1 Share this post Link to post
dkounal 3 Posted November 9, 2020 On 11/4/2020 at 12:25 PM, TigerLilly said: Maybe this can help you: https://github.com/spinettaro/delphi-event-bus With the last modifications, I decided to use EventBus finally. Thank you very much TigerLilly 1 Share this post Link to post