Thread - How to Call a Form within an iTask Thread?

Asked

Viewed 1,234 times

2

In Delphi 10.2, I have a Form A that has a Ttask "Task-A" that fires a Storedprocedure in the Oracle bank with Firedac. Storedprocedure updates a table of results that will be used by a form B which has a graph. I would like to call Form B inside a "Task-B" Ttask, which calls Forms B with the graph and can return to Form A, while the graph is updating in the other Forms B ! I used the following command to open Form B inside a Ttask , BUT FROZE THE APPLICATION ! Thanks for the personal help !

procedure TFormA.SpeedButtonChamaGrafico(Sender: TObject);
var
   Tarefaproc, Tarefagrafico : iTask;
begin

// Chamada da StoredProcedure dentro da TTask ==>  funciona corretamente !!

Tarefaproc := TTask.Create( procedure ()
                            begin
                                 with FDStoredProc1 do
                                 begin
                                      Prepare;
                                      Params[0].Value := StrToInt(EditCenario.Text);
                                      Execproc;
                                  end;
                             end);
          Tarefaproc.Start;


// Logo em seguida, chamada do FormB dentro de outra TTASK ==> DÁ ERRO, congela a aplicação !!

Tarefagrafico := TTask.Create( procedure ()
                               begin
                                   try
                                      Application.CreateForm(TformB,FormB);
                                      FormB.ShowModal;
                                   finally
                                      Freeandnil(formB);
                                   end;
                               end);
Tarefagrafico.Start;
  • I believe the freeze is given ShowModal, note that the task cannot be terminated automatically, in which case it would be stopped at ShowModal disconnected from the main application. Test the Show and tell us the result.

  • @Junior, I will make this modification along with the proposal by Kelver, below. Thank you.

  • @Junior, I tested the show . When I use Formb.show the Forms appears and scarf on the screen , in a blink ! As the Form is the main application, open with showmodal , from it I call the Formb with another showmodal thus becoming the focus and not allowing to return to the Form. Is there any other way to allow you to switch focus between two open forms ? I appreciate your help.

  • The control is done only by Modal the problem is that the Thread is unlinking the "B" from the main application.

  • 1

    @Junior, I found the mistake! It was obvious , but my lack of experience did not allow us to immediately see that the call from Formb.Show was inside a Try.. Finally , as the last Finally command was Freeandnil(formB), this obviously closed and ended the form right after the Show. I took it and it worked ! Thank you so much for your support and tips !

1 answer

2

First of all it is important to note that EVERYTHING that is done in the UI of VCL applications happens in the Main Thread (main thread), that is, it is useless to call a Form in a thread, because this will be processed by the main thread. In these cases one should even use a synchronization method so that only the main thread works in that instant of time, example:

//considerando que este código está dentro de uma thread
...
TThread.Synchronize(nil, procedure begin
  MeuForm.Show;
end);

That said, you can call your form B out of a thread and, within it, query the table that the "thread A is feeding" without problems.

It is also important to note that database objects (Queries, Sps, etc.) used within a thread NEED their own connection object, for the exclusive use of that thread. In other words, each thread NEEDS to have its connection to the BD.

Regarding to allow Forma to be accessed while Formb is visible, as already commented by @júnior-Moreira, it is only possible to use the Show, without Modal.

Hugs!

  • I understood the concept ! I will apply it and see the result. On the issue of the database connection for the exclusive use of Thread, in fact something strange happened, because I use a datamodule and had access to the database error. I decided to put a connection and a Tstoredproc inside the form itself. Is this the correct way to make the unique connection of the thread ? Can you give me some documentation ? Thank you very much !

Browser other questions tagged

You are not signed in. Login or sign up in order to post.