Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Call a form inside an iTask frozes the application, why ?


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Oct 15, 2017 5:30 PM Last Post By: Jose Silva
Jose Silva

Posts: 20
Registered: 11/1/11
Call a form inside an iTask frozes the application, why ?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 7, 2017 11:28 PM
Hi guys , I need your valuable help to undesrtand the behaviour of iTask and Form together., I'm getting an error and couldn't solve it alone.
In Delphi 10 I have a FormA that calls an Oracle stored procedure inside an iTask (thread) "Tarefaproc". This storedproc updates a table that will be used by a Tchart in another FormB . I'm calling FormB, just after the first iTask Tarefaproc, also using another iTask with the purpose to have the FormA and FormB executing in parallel. When I run the second iTask that calls FormB it frozes the application !! I appreciate your help to understand and solve this issue . See my code :

// In FormA I have a Button to call a stored procedure and after that open  FormB 
    procedure TFormA.SpeedButtonCallFormB(Sender: TObject);
    var
       Tarefaproc, Tarefagrafico : iTask;
    begin
    
    // Call StoredProc inside iTask ==>  this WORKS PERFECTLY !!
    
    Tarefaproc := TTask.Create( procedure ()
                                begin
                                     with FDStoredProc1 do
                                     begin
                                          Prepare;
                                          Params[0].Value := StrToInt(EditCenario.Text);
                                          Execproc;
                                      end;
                                 end);
              Tarefaproc.Start;
    
    // Next, calls FormB inside another iTASK ==> DOESN'T WORK , it frozes the application !
    
     Tarefagrafico := TTask.Create(
                                  procedure ()
                                  begin
                                       try
            			                  Application.CreateForm(TformB,FormB);
                                          FormB.ShowModal;
                                       finally
                                          Freeandnil(formB);
                                       end;
                                  end);
      Tarefagrafico.Start;
    end;

Edited by: Jose Silva on Oct 7, 2017 11:28 PM

Edited by: Jose Silva on Oct 7, 2017 11:29 PM

Edited by: Jose Silva on Oct 7, 2017 11:30 PM
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Call a form inside an iTask frozes the application, why ? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2017 12:15 AM   in response to: Jose Silva in response to: Jose Silva
Jose Silva wrote:

Hi guys , I need your valuable help to undesrtand the behaviour of
iTask and Form together., I'm getting an error and couldn't solve it
alone. In Delphi 10 I have a FormA that calls an Oracle stored
procedure inside an iTask (thread) "Tarefaproc". This storedproc
updates a table that will be used by a Tchart in another FormB . I'm
calling FormB, just after the first iTask Tarefaproc, also using
another iTask with the purpose to have the FormA and FormB executing
in parallel. When I run the second iTask that calls FormB it frozes
the application !! I appreciate your help to understand and solve
this issue . See my code :

The visual part of the Delphi library (VCL forms, controls etc.) is not
thread-safe. You cannot safely create such objects in a secondary
thread, not can you access such objects created in the main thread from
a secondary thread.

Most of this limitation comes from design decisions Borland (at that
time) made for the vcl; which were at least in part determined by the
way windows handles UI elements (windows) in the context of secondary
threads.

To access UI elements from a secondary thread you need to use the
TThread.Synchronize method to delegate that part of the code to the
main thread. That makes things like showing a form modally from a
secondary thread impractical, you may as well do it from the main
thread.



// In FormA I have a Button to call a stored procedure and after that
open  FormB     procedure TFormA.SpeedButtonCallFormB(Sender:
TObject);     var
       Tarefaproc, Tarefagrafico : iTask;
    begin
    
    // Call StoredProc inside iTask ==>  this WORKS PERFECTLY !!
    
    Tarefaproc := TTask.Create( procedure ()
                                begin
                                     with FDStoredProc1 do
                                     begin
                                          Prepare;
                                          Params[0].Value :=
StrToInt(EditCenario.Text);
Execproc;                                       end;
                                 end);
              Tarefaproc.Start;
    
    // Next, calls FormB inside another iTASK ==> DOESN'T WORK , it
frozes the application !      
     Tarefagrafico := TTask.Create(
                                  procedure ()
                                  begin
                                       try
            			                  Application.CreateForm(TformB,FormB);
                                          FormB.ShowModal;
                                       finally
                                          Freeandnil(formB);
                                       end;
                                  end);
      Tarefagrafico.Start;
    end;

Edited by: Jose Silva on Oct 7, 2017 11:28 PM

Edited by: Jose Silva on Oct 7, 2017 11:29 PM

Edited by: Jose Silva on Oct 7, 2017 11:30 PM


--
Peter Below
TeamB

Jose Silva

Posts: 20
Registered: 11/1/11
Re: Call a form inside an iTask frozes the application, why ? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 15, 2017 5:30 PM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:
Jose Silva wrote:
Peter , its clear now. Thanks for the support and explanations.

Hi guys , I need your valuable help to undesrtand the behaviour of
iTask and Form together., I'm getting an error and couldn't solve it
alone. In Delphi 10 I have a FormA that calls an Oracle stored
procedure inside an iTask (thread) "Tarefaproc". This storedproc
updates a table that will be used by a Tchart in another FormB . I'm
calling FormB, just after the first iTask Tarefaproc, also using
another iTask with the purpose to have the FormA and FormB executing
in parallel. When I run the second iTask that calls FormB it frozes
the application !! I appreciate your help to understand and solve
this issue . See my code :

The visual part of the Delphi library (VCL forms, controls etc.) is not
thread-safe. You cannot safely create such objects in a secondary
thread, not can you access such objects created in the main thread from
a secondary thread.

Most of this limitation comes from design decisions Borland (at that
time) made for the vcl; which were at least in part determined by the
way windows handles UI elements (windows) in the context of secondary
threads.

To access UI elements from a secondary thread you need to use the
TThread.Synchronize method to delegate that part of the code to the
main thread. That makes things like showing a form modally from a
secondary thread impractical, you may as well do it from the main
thread.



// In FormA I have a Button to call a stored procedure and after that
open  FormB     procedure TFormA.SpeedButtonCallFormB(Sender:
TObject);     var
       Tarefaproc, Tarefagrafico : iTask;
    begin
    
    // Call StoredProc inside iTask ==>  this WORKS PERFECTLY !!
    
    Tarefaproc := TTask.Create( procedure ()
                                begin
                                     with FDStoredProc1 do
                                     begin
                                          Prepare;
                                          Params[0].Value :=
StrToInt(EditCenario.Text);
Execproc;                                       end;
                                 end);
              Tarefaproc.Start;
    
    // Next, calls FormB inside another iTASK ==> DOESN'T WORK , it
frozes the application !      
     Tarefagrafico := TTask.Create(
                                  procedure ()
                                  begin
                                       try
            			                  Application.CreateForm(TformB,FormB);
                                          FormB.ShowModal;
                                       finally
                                          Freeandnil(formB);
                                       end;
                                  end);
      Tarefagrafico.Start;
    end;

Edited by: Jose Silva on Oct 7, 2017 11:28 PM

Edited by: Jose Silva on Oct 7, 2017 11:29 PM

Edited by: Jose Silva on Oct 7, 2017 11:30 PM


--
Peter Below
TeamB

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02