Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 235
  • Last Modified:

Threads and Forms

I have a program using two forms, a controlform and a displayform. The displayform contains a Thread form that does some calculations and then draws onto the canvas of an image in the diplayform (which is not visible). As soon as it does this the thread does not perform any further operations. If I replace the thread by a regular procedure the whole thing works fine, exceipt for the fact that the calculations take a while, and the program does not respond during that time.

Any ideas? Thanks in advance.
0
simondittami
Asked:
simondittami
  • 6
  • 2
  • 2
  • +3
1 Solution
 
pjdbCommented:
do you create the thread with MyThread.Create(True) ? If yes, then you need to call MyThread.Execute or anything of this kind.
If you create the thread with MyThread.Create(False);, your caclulation need to be in the execute procedure.
in any case, do not forgot the override; after lthe exectue procedure declaration and the inherited execute; in it's execution.

JDB
0
 
viktornetCommented:
Use Application.ProcessMessages;

Regards,
Viktor Ivanov
0
 
simondittamiAuthor Commented:
That does not seem to solve the problem, wherever I put it. Perhaps you could be more specific about how I should use it.

Thanks anyway, Simon

As for JBD: I use MyThreaclass.crate(false); MyThreadclass.execute is followed by override; in the head of the unit
It contains the calculation, which also seems to work fine, until it starts setting Pixels on the canvas of an image in the Displayform.
I'm a newbie in delphi, and I'm afraid I don't know what the inherited Execute is!

Any further help would be greatly appreciated.

Simon
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
viktornetCommented:
Insert that in the Execute method or where you go the big procedure that slows down your app so it doesn't respond.////

//Vik
0
 
simondittamiAuthor Commented:
I've tried, but it does not seem to solve my problem. The programm still seems to crash.

Thanks for trying!
0
 
simondittamiAuthor Commented:
Adjusted points to 105
0
 
XiaoChenCommented:
Use Win API CreateThread
and do the calculation in the new thread.
when this calculating thread ends,
save result to a global memory zone and
send a message to one of your window
to notify the display form refresh the content
0
 
kretzschmarCommented:
hi simon,

give me me your email address, i will send you the source of a little application which use threads and forms as sample.

meikl
0
 
simondittamiAuthor Commented:
This would of course work, but unfortunately the "result" is  a 40 MB image, having 2 40 MB images in my RAM or on the harddisk is what I'm trying to avoid. (if you know a way of avoiding that please anwer again.

Thank you, though.


0
 
simondittamiAuthor Commented:
ok - sounds good. My email is sdittami@degnet.baynet.de

if that works, you get the points.
0
 
bcrotazCommented:
No no no....
The clue was in an earlier mail when you said that the calculation worked, but as soon as you drew pixels, it stopped working.

The problem is that the Delphi VCl is not thread safe.  In a nut-shell, it means that if you call and VCl object methods from inside a thread object, you must Synchronize them.  What that means in actual fact is that (behind the scenes) the thread object sends a Windows message to the VCL, telling it to call a method in your thread.  This means that the method is executed in the context of the VCL thread, not your thread.  Confusing, isn't it!  This should make it clear:

  TMyThreadObj = Class(TThread)
    private
      FSomeData: String; // this data is required by your draw routine
    protected
      procedure Execute; override;
      procedure DoDraw;
  end;

procedure TMyThreadObj.Execute;
begin
  // Do Calculation here
  // When you need to draw a pixel
  // Set the private data for the pixel location and color etc
  FSomeData:='Here goes the data';
  // Now call the DoDraw method via Synchronize
  Synchronize(DoDraw); // easy, isn't it!
end;

procedure TMyThreadObj.DoDraw;
begin
  // This must always be called via Synchronize
  MainForm.DrawPixelsMyWay; // do your drawing here
end;
0
 
simondittamiAuthor Commented:
Yeah - That's Great.
---- Thank you. The points are yours.

I still wonder why Application.ProcessMessages did not work and also why my program runs faster now than it did before without threads ???

Best whishes, Simon
0
 
bcrotazCommented:
Because Application.ProcessMessages goes away to process all messages from the mouse, keyboard, disk etc, then comes back to your code.  And while your code is waiting for the disk or the screen, nothing happens.  With threads, the other bits of code can be executing while another thread is waiting on a resource.

Just be careful about synchronisation.  It's something that has to be designed in.  If you try to do without, then add it, your code will randomly lock up, as you get race conditions and deadlocks appearing.  There's a couple of very good books on the subject.  Go to Amazon.com and search for 'win32 threads'.  Be aware that the examples are in C, but they're very clearly commented, so you can see the theory without having to understand the language (I don't read C).  It's nt an easy subject to get your head round, but well worth doing so.  It's taken me about 2 months to understand them, and my software package now has more than ten simultaneous threads.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 6
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now