Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Fun With Async Methods 2

Status
Not open for further replies.

Glenn9999

Programmer
Jun 19, 2004
2,311
US
One thing I've been trying to do is get an asynchronous procedure call done (drops out when set up, fires event when done, but lets the logic continue to run afterwards). Basically put, the procedure starts up a thread and then exits, and then there is an event which fires when the procedure thread completes. The idea is to stay away from the main (VCL) thread as much as possible, except for update events.

Now, the logic is pretty simply devised and seems to work well when it comes to simple things, but harder when it comes to adding loops and other processing.

In a basic way I have something like:
Code:
MyObject.DownloadFile;

procedure MyComponent.MyObjectCompleted(Sender: TObject);
begin

end;

when it comes to this async procedure.

Is there a smart way to handle loop & conditional logic in such a situation? E.g. if it were synchronous (doesn't go to the next statement until completely done):

pretty simplified logic regarding what I'm trying to do:
Code:
for i := 0 to (ListBox.Items.Count - 1) do
  if ListBox.Selected[i] then
  if StringList.Count > 0 then
    for j := 0 to (StringList.Count - 1) do
      begin
        MyComponent.URL := StringList.Strings[j];
        upteststr := UpperCase(MyComponent.Url);
        if Condition1 or Condition2 then
          DownloadFile;
      end;

"DownloadFile" in this case has my normal async procedure call, but with a "ProcessMessages" loop after it. Anyhow in the logic, the async call needs to complete before the loop continues.

Any ideas for a way to approach this where the logic wouldn't be so convoluted, or would this be a case where it might be better to just have the "ProcessMessages" loop and be done with it?

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
the whole point of going async is to do more work at the same time (if your machine has multiple cores, which is more and more likely these days);

so if you need to download files from multiple url's spawn a number of threads doing the work.
This is a typical producer/consumer scenario, Martin Harvey explains it nicely here:

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Thanks for your help.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Here's the downloader component code that I've been working on. It seems to work right as it is. Any constructive suggestions or ideas for improvement always welcome!

faq102-7504

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
I updated what I've been working on (link above). If anyone can give any advice on how to stabilize it, it would be appreciated. I still have it crashing with AVs (some of which are fixed by using Application.ProcessMessages after the call) or hanging every so often. So what am I doing wrong on this that it's not ever getting stable?

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
I have learned that the more I remove Application.ProcessMessages (from like everywhere) things become very stable - yet non-responsive too.

JD Solutions
 
Yeah that's kinda been the issue. Trying to get things to be reasonably responsive, yet not hang (app goes to "Not Responding" sometimes), or crash with AVs. Just work. For the full project I'm using that in, 95% of the issues with it have been with this particular component. It gets frustrating.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
A little update. Actually, thinking on thread102-1660895 actually gave me an idea for my blocking loop. That cleared up a couple of problems I've been having.

The other major one (why I think I get my "Not Responding" messages every so often) might be solvable by this general concept. I think a lot of my problems come from the message status on the main thread.

The "Not Responding" status (my guess) is because the worker thread gets hung up trying to contact/read from the web site and the main thread sits empty too long. I'm wondering if maybe my AVs, fixed by use of Application.ProcessMessages, are because the main thread is getting behind on handling messages?

Anyhow my thought was just the use of a TTimer and just send the Progress event notification every 1-2 seconds no matter what, but that hung up immediately, too.

Any thoughts are welcome on this.

(Commentary, not necessarily related to anyone here but in general for my research on this)
As for research on this, I am definitely finding the support aspect on threads in most web sites are very limited when it comes to debugging and creating threaded processes. Unfortunately, most of the "characters" (as it were, substituting for the old phrase "ink" as for print media) get spent on making boogeymen up for reasons never to use Application.ProcessMessages, and pointing to threads, yet offering very little to no support on how to design, code, and debug the problems associated with threads. One of these web pages even complained about an application vendor's use of Application.ProcessMessages. When a reasonably popular application vendor with (no doubt) access to Embarcadero Tech Support resorts to this, there should be some hard questions asked as to the level of support out there.

The MartinC text is pretty good from a theory standpoint, but it's pretty hard to jump to practice when it comes to a bunch of theory. Even with "regular" programming, there still was the opportunity in learning from text and otherwise the kinds of issues that would come up and how to diagnose their causes and fix them (i.e. "if a happens this means b, so do c"). Even after 10+ years of Delphi, I'm not seeing any of this with respect to threads, or even help on designing and debugging threaded processes, but I'm seeing mountains of text pushing people away from using Application.ProcessMessages.

Now granted, being a hobbyist programmer, all I'm out on for not making this work in a timely fashion is my time and frustration. But if I were doing this with a deadline and
expectation of code quality, I would have abandoned thread use long ago as unworkable. And from what I'm seeing most are doing the same.

Those that are the "punditry" in Delphi (by virtue of being in official support or having "industry accepted" blogs): Why not stop being so negative in general about the option that people can handle and support, and start trying to help people handle and support what you are wanting to push them towards?
(/Commentary)

Footnote: After writing the code referenced in the FAQ, I did write a couple of file-based threading processes which work wonderfully with no bugs, so the time wasn't completely lost for me from an educational standpoint.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top