On Sun, 26 Nov 2006 23:16:50 +0100, Matthew Comb <[EMAIL PROTECTED]> 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

_______________________________________________
Delphi mailing list
[email protected]
http://ns3.123.co.nz/mailman/listinfo/delphi

Reply via email to