View Issue Details

IDProjectCategoryView StatusLast Update
0002519JEDI VCL00 JVCL Componentspublic2005-01-24 04:36
ReporterDierkAssigned Toobones 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.00 BETA 2 
Target VersionFixed in Version3.00 
Summary0002519: JvHttpUrlGrabber freezes application
DescriptionI run into trouble when I use JvHttpUrlGrabber in a chain.

Like following. I think it´s a problem with threads - But how should I do
that?
======================================================
JvHttpUrlGrabber.url:='http://www.xyz.com/file1.txt'
JvHttpUrlGrabber.start

procedure TForm1.JvHttpUrlGrabber1DoneFile(Sender: TObject;
  FileName: String; FileSize: Integer; Url: String);
begin

   If fileexists(filename) then
   begin
     .... open the file and read some infos and then download second file
     JvHttpUrlGrabber.url:='http://www.xyz.com/file2.txt'
     JvHttpUrlGrabber.start
   end;

end;


======================================================
The application freezes.
I think it is because, the "first" thread of the grabber is not finished
until it is still in procedure JvHttpUrlGrabber1DoneFile.

Regards
Dierk
TagsNo tags attached.

Activities

obones

2005-01-17 12:46

administrator   ~0006188

Your assumption is right. Could you try this:
In JvUrlListGrabber.pas, at line 878, replace this
  FreeAndNil(FUrlGrabberThread);

By
  FUrlGrabberThread.Terminate;

Then rebuild the JVCL packages and your application.
Note that this introduces a memory leak (the thread is never freed) and as such must not be put into production code. But once I know that this works, I'll be able to further work on this to get rid of the memory leak.

Dierk

2005-01-18 00:15

reporter   ~0006196

Hi Olivier,
no I think this is not the right way. It should not be possible to start same grabber in that time. For this way we should use an additional grabber.

Therefore the grabber shouldn´t start again, before "old" grabber thread is ended. I also run in troubles, when I watch "status" of the grabber until is not set to gsstopped, like this:
=====================
grabber1.url:='xy1';
grabber1.start; //download file1
while grabber1.status=gsstopped do
  do application.processmessages;
grabber1.url:='xy2';
grabber1.start; //download file2
=====================

Run into exceptions....
At this point I would prefer to ask if thread is terminated to if status is gsstopped

Greetings

anonymous

2005-01-18 00:50

viewer   ~0006197

But when you are in the OnDoneFile event, the thread is NOT terminated yet. It is still running, but halted to be synchronized with the main thread. Now, if you call Start, it will try to kill that thread, and hence be blocked because it's inside itself.
My change ensures that there is no blocking if you call start from an event. But that change is not clean.
What it should actually do is to call Stop before starting a new one. I'll investigate that.

As to your code, it is very dangerous to have a loop that calls ProcessMessage like that. You should use the chaining of events.

In the end, you, as the user, don't need to know there is a thread. This is just an implementation detail that should have no impact on your code. Basically, I could decide that the thread is stopped much later after the end of the download.

I'll investigate that and will do further testing.

jfudickar

2005-01-18 01:19

developer   ~0006198

Isn't it possible to use the urlgrabber without a thread, and then make the thread handling outside manually?

Dierk

2005-01-18 01:25

reporter   ~0006199

For my usage it is a very easy and smoothy way to have a httpgrabber that do not slowdown my application until it grabs something from internet.
I really like this component. It is one of my favorits.

obones

2005-01-18 01:39

administrator   ~0006200

(that anonymous post was from me)

Jens: No it is not even an option. It is being used by the TJvUrlListGrabber component which in essence is asynchronous.
I won't change that.
What I will fix though is the way the thread is used so that calling Start on an already started thread from one its own events doesn't freeze the application.
Not too hard, I just need some time to implement it.

jfudickar

2005-01-18 02:23

developer   ~0006202

@Olievier:I didn't want to remove the threads. But what about an property to work without thread!

anonymous

2005-01-19 08:30

viewer   ~0006228

One more bug:

Stopping a JvHttpUrlGrabber through method stop when grabber isn´t started causes an AV!
But I don´t know why.

obones

2005-01-22 05:16

administrator   ~0006247

> @Olivier:I didn't want to remove the threads. But what about an
> property to work without thread!

But then, how do you make it asynchronous when the API calls are synchronous?


> Stopping a JvHttpUrlGrabber through method stop when grabber
> isn´t started causes an AV!
> But I don´t know why.

That one was easy, it's as stupid bug because the thread is not created yet. This is now fixed in CVS.

Further, the chaining problem is fixed as well, and the fix does not introduce any memory or resource leak AFAIK.
Please use the latest version from CVS and let us know how it goes

jfudickar

2005-01-24 00:24

developer   ~0006262

> > @Olivier:I didn't want to remove the threads. But what about an
> > property to work without thread!

> But then, how do you make it asynchronous when the API calls are synchronous?

This exactly what i want. I want to use it synchronous. For example in the TJvProgramVersionCheck i already have implemented a thread for handling the download's and check's. In this case i need it synchronous.

obones

2005-01-24 01:22

administrator   ~0006263

> This exactly what i want. I want to use it synchronous. For example in
> the TJvProgramVersionCheck i already have implemented a thread for handling
> the download's and check's. In this case i need it synchronous.

I understand, but those components are not meant to be synchronous. If they were, they would be locking up the application for the duration of the download, which can be quite long.
Use the events, and you should be able to do what you want, but have the advantage to not freeze the application.

Dierk

2005-01-24 01:25

reporter   ~0006265

Olivier,
great work. It works now as far as I ´ve tested good.
@Jens: What and where is the TJvProgramVersionCheck?

obones

2005-01-24 04:36

administrator   ~0006267

The class from Jens is under dev/Jens/JvProgramVersionCheck in CVS. Alternatively, you can see it online here:
http://cvs.sourceforge.net/viewcvs.py/jvcl/dev/Jens/JvProgramVersionCheck/

Issue History

Date Modified Username Field Change
2005-01-17 06:40 Dierk New Issue
2005-01-17 06:41 obones Status new => assigned
2005-01-17 06:41 obones Assigned To => obones
2005-01-17 12:46 obones Note Added: 0006188
2005-01-17 12:46 obones Status assigned => feedback
2005-01-18 00:15 Dierk Note Added: 0006196
2005-01-18 00:50 anonymous Note Added: 0006197
2005-01-18 01:19 jfudickar Note Added: 0006198
2005-01-18 01:25 Dierk Note Added: 0006199
2005-01-18 01:39 obones Note Added: 0006200
2005-01-18 02:23 jfudickar Note Added: 0006202
2005-01-19 08:30 anonymous Note Added: 0006228
2005-01-22 05:16 obones Note Added: 0006247
2005-01-24 00:24 jfudickar Note Added: 0006262
2005-01-24 01:22 obones Note Added: 0006263
2005-01-24 01:25 Dierk Note Added: 0006265
2005-01-24 04:36 obones Status feedback => resolved
2005-01-24 04:36 obones Fixed in Version => 3.00
2005-01-24 04:36 obones Resolution open => fixed
2005-01-24 04:36 obones Note Added: 0006267