Link to home
Start Free TrialLog in
Avatar of Ivanov_G
Ivanov_GFlag for Bulgaria

asked on

URGENT: Problem with threads

I have input file - plain text in the format:
1
2
3
...

I use this file for open URL, submit the value as a parameter, retrieve some info and save it to file. I use a dynamic array of TMyThread type. Let's say I set its length to 30. Then loop through Low() and High() and check if the element is nil - create the thread. If it is not - check if it is running (public var in the thread). I set FreeOnTerminate = True, but somehow the thread is not nil after it finished.

I the loop if the thread has finished (it should be nil because FreeOnTerminate = True) I create a new instance. But Somehow the finished thread is not nil... I create it with CreateSuspended = False...
Avatar of vadim_ti
vadim_ti

FreeOnTerminate only destroy thread, but will not assign nil  to thread variable,
you can nil array element in onDestroy method of your thread
think abot it, you can save Thread object in number of different variables, thread could not to nil them (and even to know
about them)
but in your on destory event you can loop through your array
for (....) {
  if (ThreadArr[i] = Self) then begin
     ThreadArr[i] := nil;
     break;
  end
Avatar of Russell Libby

It would actually be better to set the OnTerminate method handler for the thread, as this will run in the context of the main thread.

OnTerminate
---------------
Occurs after the thread's Execute method has returned and before the thread is destroyed.

property OnTerminate: TNotifyEvent;

Description

Write an OnTerminate event handler to execute code after the thread finishes executing. The OnTerminate event handler is called in the context of the main VCL thread, which means VCL methods and properties can be called freely. The thread object may also be freed within the event handler.


---

Regards,
Russell
Avatar of Ivanov_G

ASKER

I think I have to clarify few things

type
   ThreadArr     : array of TMyThread;

    for counter := Low(ThreadArr) to High(ThreadArr) do
      begin
        if ThreadArr[counter] = nil then
          begin
            if InputStrings.Count > 0 then
              begin
                ThreadArr[counter] := TMyThread.Create(False, ThreadOptions, InputStrings[0]);
                InputStrings.Delete(0);
              end;
          end
        else
          if ThreadArr[counter].IsFinished then
            begin
              ThreadArr[counter].Terminate;
              ThreadArr[counter] := nil;
            end;
      end;

This is the case here... Is finished is public variable in the thread which shows me if everything with the HTTP ended correctly...
SOLUTION
Avatar of vadim_ti
vadim_ti

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Oops, posted too quick...

another example of execute without looping

procedure TMyThread.Execute;
begin

  // perform first step
  ....

  if not(Terminated) then
  begin
     //  next step
     ....
     if not(Terminated) then
     begin
        // next step
        ....
        etc....
     end;
  end;

end;

----
Regards,
Russell
weird pooling scheme if it is ment to be one
for a thread pool check for example Indy's ThreadPool
the threads that finish just get suspended .. when needed nonworking threads get returned, if no thread is free a new one is created
think of something in the lines of:
while InputStrings.Count > 0 do
begin
  thd:=ThreadPool.GetAvailableThread(true {allow create});
  thd.ProcessURL(InputStrings[InputStrings.Count-1]);
  InputStrings.Delete(InputStrings.Count-1);
end;

with proper locking you could make this 'live' :)
somehow ... some of the thread fails. If I run it once, it can finish successfully, but the second time, some thread will fail and this will stop the whole application...

I am trying to debug this now, but with so many threads ... grrr