elGringo Posted February 9, 2018 Share Posted February 9, 2018 Hi, trying example ProgressBar with forEach but! doesn't work... vcl example looks like this and works perfectly unit test_55_ForEachProgress; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, OtlTask, OtlParallel; type TfrmForEachWithProgressBar = class(TForm) btnStart : TButton; pbForEach: TProgressBar; procedure btnStartClick(Sender: TObject); private FPosition: integer; FProgress: integer; FWorker : IOmniParallelLoop<integer>; procedure IncrementProgressBar; end; var frmForEachWithProgressBar: TfrmForEachWithProgressBar; implementation {$R *.dfm} const CNumLoop = 20000; procedure TfrmForEachWithProgressBar.btnStartClick(Sender: TObject); begin btnStart.Enabled := false; pbForEach.Max := 100; pbForEach.Position := 0; pbForEach.Update; FProgress := 0; FPosition := 0; // reference must be kept in a global field so that the task controller is not destroyed before the processing ends FWorker := Parallel .ForEach(1, CNumLoop) .NoWait // important, otherwise message loop will be blocked while ForEach waits for all tasks to terminate .OnStop( procedure (const task: IOmniTask) begin // because of NoWait, OnStop delegate is invoked from the worker code; we must not destroy the worker at that point or the program will block task.Invoke( procedure begin FWorker := nil; btnStart.Enabled := true; end ); end ); FWorker.Execute( procedure (const task: IOmniTask; const i: integer) begin // do some work Sleep(1); // update the progress bar // we cannot use 'i' for progress as it does not increase sequentially // IncrementProgressBar uses internal counter to follow the progress task.Invoke(IncrementProgressBar); end ); end; procedure TfrmForEachWithProgressBar.IncrementProgressBar; var newPosition: integer; begin Inc(FProgress); newPosition := Trunc((FProgress / CNumLoop)*pbForEach.Max); // make sure we don't overflow TProgressBar with messages if newPosition <> FPosition then begin pbForEach.Position := newPosition; FPosition := newPosition; end; end; end. On UniGUI i tried... ProgressBar.Max := 100; ProgressBar.Position := 0; ProgressBar.Update; FProgress := 0; FPosition := 0; // reference must be kept in a global field so that the task controller is not destroyed before the processing ends FWorker := Parallel.ForEach(1, CNumLoop).NoWait // important, otherwise message loop will be blocked while ForEach waits for all tasks to terminate .OnStop( procedure(const task: IOmniTask) begin // because of NoWait, OnStop delegate is invoked from the worker code; we must not destroy the worker at that point or the program will block task.Invoke( procedure begin FWorker := nil; //btnStart.Enabled := true; end); end); FWorker.Execute( procedure(const task: IOmniTask; const i: integer) begin // do some work Sleep(1); // update the progress bar // we cannot use 'i' for progress as it does not increase sequentially // IncrementProgressBar uses internal counter to follow the progress task.Invoke(IncrementProgressBar); end); procedure TForeCastSalesByDayCalcFrame.IncrementProgressBar; var newPosition: integer; begin Inc(FProgress); newPosition := Trunc((FProgress / CNumLoop) * ProgressBar.Max); // make sure we don't overflow TProgressBar with messages if newPosition <> FPosition then begin ProgressBar.Position := newPosition; FPosition := newPosition; end; end; What's wrong? Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 9, 2018 Author Share Posted February 9, 2018 Async example seems doesn't work too Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 9, 2018 Author Share Posted February 9, 2018 begin bForeCastForDevice.Enabled := false; Parallel.Async( procedure begin // executed in background thread Caption := 'Work...'; Sleep(500); // MessageBeep($FFFFFFFF); end, Parallel.TaskConfig.OnTerminated( procedure(const task: IOmniTaskControl) begin // executed in main thread bForeCastForDevice.Enabled := true; Caption := 'Ready'; end)); end; Quote Link to comment Share on other sites More sharing options...
Oliver Morsch Posted February 9, 2018 Share Posted February 9, 2018 I think the problem is that a webapp always works with request -> response. No active request, no response possible. Due to the Async/Nowait you have: request -> response -> Callback function (but here is no request), Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 9, 2018 Author Share Posted February 9, 2018 sucks( as usual will use httpServer on Indy... Quote Link to comment Share on other sites More sharing options...
rgreat Posted February 9, 2018 Share Posted February 9, 2018 You could use synchronous unigui mode. Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 9, 2018 Author Share Posted February 9, 2018 thnks, but already in sunc mode Quote Link to comment Share on other sites More sharing options...
aristeo Posted February 9, 2018 Share Posted February 9, 2018 To implement a ProgressBar try the attached code. Main.zip Quote Link to comment Share on other sites More sharing options...
rgreat Posted February 9, 2018 Share Posted February 9, 2018 thnks, but already in sunc mode Use UniSession.Synchronize; then. Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 9, 2018 Author Share Posted February 9, 2018 Thanks, caisistemas! Interesting solution with ajax. Also thought about it. The more i work with UniGUI the more i understand - "first try ajax")) rgreat What you mean UniSession.Synchronize ? Quote Link to comment Share on other sites More sharing options...
rgreat Posted February 11, 2018 Share Posted February 11, 2018 for i:=0 to 100 do begin pbForEach.Position := i; UniSession.Synchronize; end; UniSession.Synchronize is more or less analogue of VCL Application.ProcessMessages; Quote Link to comment Share on other sites More sharing options...
elGringo Posted February 11, 2018 Author Share Posted February 11, 2018 hm... need to try thnks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.