[DUG] Program crashes - anyone knows why?
Gajo Csaba
csaba at enyem.com
Mon Nov 27 11:35:18 NZDT 2006
On Sun, 26 Nov 2006 23:16:50 +0100, Matthew Comb <matt at ferndigital.com>
wrote:
> Sorry if Im stating the obvious.
No problem Matt it is usually the most obvious things that go wrong ;)
> Have you suspended your threads before assigning any of their properties
> ?
> This can cause problems.
Hmmm yeah I create each thread as
thread := QueryThread.Create(true); // true = start suspended
I think that should do it, right?
> What does your thread execute do aside from update the GUI in your syn
> routine? Does it access anything else application wide? or any local
> files?
It accesses the two lists which are global. But they are TThreadLists so I
shouldn't be doing any synchronization.
Each thread accesses the GetInetFile method alot, so this can be the weak
point of the application. But I cannot synchronize this method, because
the point of the threads is to make the downloading faster. If each thread
had to wait for another to finish downloading a page from the internet
then there would be no point for using threads.
I've read about the WinAPI functions I'm using in this method and they are
all thread safe, according to MSDN.
Here's the method itself. I'll explain the relevant parts in comments.
var
ENABLE_CACHING: boolean; // global variable
function GetInetFile(const fileURL, FileName: String; proxy:
TProxyAddress): boolean;
const BufferSize = 1024;
var
hSession, hURL: HInternet;
Buffer: array[1..BufferSize] of Byte;
BufferLen: DWORD;
f: File;
sAppName,error: string;
caching: boolean;
critical: _RTL_CRITICAL_SECTION; // used for critical section
begin
Result := False;
InitializeCriticalSection(critical); // here I am accessing the
ENABLE_CACHING
EnterCriticalSection(critical); // global variable, so I use a
critical
caching := ENABLE_CACHING; // section for synchronizing
LeaveCriticalSection(critical);
DeleteCriticalSection(critical);
error := '';
sAppName := ExtractFileName(Application.ExeName);
if proxy = nil then
hSession := InternetOpen(PChar(sAppName), // this function starts the
session
INTERNET_OPEN_TYPE_PRECONFIG, // it should be thread-safe
nil, nil, 0)
else
hSession := InternetOpen(PChar(sAppName), // configure to use a proxy
INTERNET_OPEN_TYPE_PROXY,
PChar(proxy^.host + ':' + IntToStr(proxy^.port)), nil, 0);
if hSession = nil then // this is for debugging
error := 'Unable to open Internet connection.';
try
if caching then
hURL := InternetOpenURL(hSession, // check if URL exists
PChar(fileURL), // this should be thread-safe
nil,0,0,0)
else // caching disabled
hURL := InternetOpenURL(hSession,
PChar(fileURL),
nil,0,INTERNET_FLAG_RELOAD,0);
if hURL = nil then
error := 'Unable to open URL: ' + fileURL;
try // now I open a new file and write the content into it
AssignFile(f, FileName);
Rewrite(f,1);
repeat
// download file from the internet, this should be thread-safe
if not InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen)
then begin
error := 'Error reading from file: ' + fileURL + #13'Maybe your
proxy is not working?';
break
end;
BlockWrite(f, Buffer, BufferLen)
until BufferLen = 0;
CloseFile(f);
Result:=True;
finally
InternetCloseHandle(hURL)
end;
finally
InternetCloseHandle(hSession)
end;
{$IFDEF Debug}
if error <> '' then
raise Exception.Create(error)
{$ENDIF}
end;
In any case, this method is inside a try-except block. So if anything goes
wrong I will catch the exception.
> Are you using Indy for your sockets? (These are components not classes)
>
> Are you using an activex controls ?
No I'm not using any custom components or libraries, most of the stuff is
by me or I've found it on the internet (like the GetInetFile method, which
is from http://delphi.about.com/od/internetintranet/l/aa013001a.htm ). I'm
trying to use the WinAPI whenever I can, I find it to be more reliable
than custom components.
The client still hasn't replied (he's from Canada so it's probably still
Sunday afternoon there :)). I've placed everything in the Execute method
into a try-except block, hopefully that will do it.
If not I'll try one of the debug libraries suggested by you guys.
Thanks for the help,
Csaba
More information about the Delphi
mailing list