Miguel E
Miguel E

Reputation: 1336

Open large query without new thread

I have a large query that needs to be loaded into memory. This query takes about 30 seconds to open. It loads immediately after the application starts, only once. During this time the application hangs. What I need to do is to update a progress bar, during the 30 seconds. I've tried to create a new thread to update the progress bar, but it will only update after the query is opened. Can anyone point a simple way to do this?

I've created a thread class:

type
   TMyThread = class(TThread)
   private
      fLowerLimit: Integer;
      fUpperLimit: Integer;

I'm creating an instance of the thread class:

   CountingThread := TMyThread.Create(0, 300, True);
   CountingThread.Resume;
   //
   SplashDlg.Show;

Inside the thread I'm just updating the progress bar:

procedure TMyThread.UpdateMainThread;
begin
   SplashDlg.ProgressBar1.Position:= SplashDlg.ProgressBar1.Position+1;
   MyDebug('UpdateMainThread:'+ IntToStr(SplashDlg.ProgressBar1.Position));
end;

The thread hangs while the query is opening.

Upvotes: 1

Views: 1060

Answers (2)

jachguate
jachguate

Reputation: 17203

You're doing it the other way around.

The UI is bound to the application main thread, so you always take care of the UI in the main thread, and do the real job in a worker thread (from there the worker name).

The way you're asking the question, you're already dealing with threads, so, just change your point of view and perform the heavy SQL load in a secondary thread while keeping your UI responsive and updated in the, now non-busy, main thread.

As for the 30 seconds wait time, really, if you can't determine exactly the load time is better to not use a progress bar, since we all hate that liar bars who don't reflect the real state of things. Your bar sometimes will show 50% and suddenly goes to 100%... or it may reach 100% while in fact the real thing is going to take ages to complete (heavy load on the server, slow network, and 1,000 other factors).

Nowadays, we all are used to the just wait indicators, like this:

enter image description here

enter image description here

enter image description here

When you see this, you know it is working, and you just have to wait until it completes.

Upvotes: 1

opc0de
opc0de

Reputation: 11768

It's better to paste some code here if you wish to get a more exact answer.

There are 2 ways in witch you can process data and have the UI responsive.

  • You can use Application.ProcessMessages in your loop.

  • Or the thread solution that you already approached.

The problem is I don't think you have a loop you are using a component and if that component doesn't call a method to show a progress you can't estimate how much time the query will take to complete. So either you show a loading... screen while te query executes without a progressbar or you tell us more about what you use for the query.

Hope it helps

Upvotes: 2

Related Questions